HDU 3308 LCIS(线段树区间合并 单点更新)
2015-08-10 10:04
507 查看
#include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<ctime> #include<iostream> #include<algorithm> #include<sstream> #include<fstream> #include<vector> #include<map> #include<stack> #include<list> #include<set> #include<queue> #define LL long long #define lson l,m,rt<<1 #define rson m+1,r,rt<<1 | 1 using namespace std; const int maxn=100005,inf=1<<29; int lsum[maxn<<2],rsum[maxn<<2],msum[maxn<<2],ln[maxn<<2],rn[maxn<<2]; void PushUp(int rt,int m)//利用子节点信息更新父节点 { lsum[rt]=lsum[rt<<1];//根节点从左边其的最长区间至少等于左儿子从左边起得最长区间 rsum[rt]=rsum[rt<<1|1]; msum[rt]=max(msum[rt<<1],msum[rt<<1|1]); ln[rt]=ln[rt<<1]; rn[rt]=rn[rt<<1|1]; if(rn[rt<<1]<ln[rt<<1|1])//左儿子区间右端点比右儿子区间左端点小 { if(lsum[rt]==m-(m>>1)) lsum[rt]+=lsum[rt<<1|1]; if(rsum[rt]==(m>>1)) rsum[rt]+=rsum[rt<<1]; msum[rt]=max(msum[rt],rsum[rt<<1]+lsum[rt<<1|1]); } } void build(int l,int r,int rt)//建树 { if(l==r) { scanf("%d",&ln[rt]); //printf("[%d,%d] = %d\n",l,r,ln[rt]); rn[rt]=ln[rt]; lsum[rt]=rsum[rt]=msum[rt]=1; return ; } int m=(l+r)>>1; build(lson); build(rson); PushUp(rt,r-l+1); //printf("msum[%d,%d] = %d\n",l,r,msum[rt]); } void update(int p,int x,int l,int r,int rt)//单点更新 { if(l==r) { lsum[rt]=rsum[rt]=msum[rt]=1; ln[rt]=rn[rt]=x; return ; } int m=(l+r)>>1; if(p<=m) update(p,x,lson); else update(p,x,rson); PushUp(rt,r-l+1); } int Query(int L,int R,int l,int r,int rt) { //区间是叶子节点或都可用或都不可用直接返回 if(L<=l&&r<=R) return msum[rt]; //if(l==r||msum[rt]==0||msum[rt]==r-l+1) return msum[rt]; int ans=0; int m=(l+r)>>1; if(L<=m) ans=max(ans,Query(L,R,lson)); if(R>m) ans=max(ans,Query(L,R,rson)); if(rn[rt<<1]<ln[rt<<1|1]) ans=max(ans,min(rsum[rt<<1],m-L+1)+min(lsum[rt<<1|1],R-m));//不能越了区间[L,R]的界 //printf("msum[%d,%d] = %d ans=%d\n",l,r,msum[rt],ans); return ans; //return max(ans,rsum[rt<<1]+lsum[rt<<1|1]); } int main() { //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); //srand(time(NULL)); int n,m,x,y,t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); char op[5]; build(1,n,1); for(int i=0;i<m;i++) { scanf("%s%d%d",op,&x,&y); if(op[0]=='U') update(x+1,y,1,n,1); else printf("%d\n",Query(x+1,y+1,1,n,1)); } } return 0; }
相关文章推荐
- 批量重读PP主数据 BDC
- 平衡二叉树的C语言实现(创建、插入、查找、删除、旋转)【数据结构】
- 2.1 数据结构-属性方法
- watchOS 2:动画的力量
- 电脑常见故障处理办法I
- opscenter dashboard排错
- opscenter dashboard排错
- opscenter dashboard排错
- AttributeError: 'module' object has no attribute 的解决方法
- 天声人語 20150810
- 【小熊刷题】reverse words in a string w. or w/o. allocating extra space
- hdu 1045 Fire Net (二分匹配)
- mysql使用命令小结
- opscenter dashboard排错
- hihocoder1032 最长回文子串
- 关于CPU过热导致主机自行断电重启的解决办法
- ios网络编程(http、socket)
- 如果大家关注SOA的事务一致性的处理,那么不妨看看我们是怎么解决的
- Android利用activity启动模式退出整个应用
- HDU 4818 RP problem 高斯消元