Splay解决区间问题[单点更新,区间最值询问]
2013-01-31 21:20
477 查看
/*http://acm.hdu.edu.cn/showproblem.php?pid=1754*/ /*单点更新,区间询问 splay实现*/ /*注意写rotateTo的时候。。*/ #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAXN = 222222; class SplayTree{ #define l(x) (ch[x][0]) #define r(x) (ch[x][1]) #define mid(x,y) (x+y)>>1 public: int ch[MAXN][2],pre[MAXN],sz[MAXN],mx[MAXN],val[MAXN],a[MAXN]; int root,tot; void init(){ memset(ch,0,sizeof(int)*MAXN*2); memset(pre,0,sizeof(int)*MAXN); memset(sz,0,sizeof(int)*MAXN); memset(mx,-1,sizeof(int)*MAXN); root = tot = 0; } void read(int n){ a[1] = a[n+2] = -1; for(int i=2;i<=n+1;i++) scanf("%d",&a[i]); } void push_up(int rt){ mx[rt] = max(max(mx[l(rt)],mx[r(rt)]),val[rt]); sz[rt] = sz[l(rt)]+sz[r(rt)]+1; } void rotate(int x,int f){ int y = pre[x]; ch[y][!f] = ch[x][f]; if(ch[y][!f]) pre[ch[y][!f]] = y; push_up(y); if(pre[y]) ch[pre[y]][r(pre[y])==y] = x; pre[x] = pre[y]; ch[x][f] = y; pre[y] = x; } void splay(int x,int goal){ while(pre[x]!=goal){ int y = pre[x], z = pre[pre[x]]; if(z==goal){ rotate(x,l(y)==x); }else{ int f = (l(z)==y); if(ch[y][!f]==x){ rotate(y,f); rotate(x,f); }else{ rotate(x,!f); rotate(x,f); } } } push_up(x); if(goal==0) root = x; } void rotateTo(int x,int goal){ int k = root; while(1){ if(x<(sz[l(k)]+1)) k = l(k); else if(x==(sz[l(k)]+1)){ break; }else{ x -= (sz[l(k)]+1); k = r(k); } } splay(k,goal); } void buildTree(int l,int r,int &rt,int f){ if(l>r)return; int m = mid(l,r); rt = ++tot; val[rt] = a[m]; pre[rt] = f; buildTree(l,m-1,l(rt),rt); buildTree(m+1,r,r(rt),rt); push_up(rt); } int query(int l,int r){ rotateTo(l-1,0); rotateTo(r+1,root); return mx[l(r(root))]; } void update(int pos,int c){ rotateTo(pos,0); val[root] = c; push_up(root); } void debug(){ printf("root:%d l(root):%d r(root):%d\n",root,l(root),r(root)); dfs(root); } void dfs(int rt){ if(!rt)return; dfs(l(rt)); printf("node:%d max:%d size:%d val:%d lson:%d rson:%d pre:%d\n",rt,mx[rt],sz[rt],val[rt],l(rt),r(rt),pre[rt]); dfs(r(rt)); } }; SplayTree spt; int main(){ int n,m; while(scanf("%d%d",&n,&m)!=EOF){ spt.init(); spt.read(n); spt.buildTree(1,n+2,spt.root,0); char op[2]; int a,b; while(m--){ scanf("%s%d%d",op,&a,&b); //spt.debug(); system("pause"); if(op[0]=='Q'){ printf("%d\n",spt.query(a+1,b+1)); }else{ spt.update(a+1,b); } } } return 0; }
相关文章推荐
- Splay解决区间问题[区间更新,区间求和]
- [HDU 5316] Magician (线段树+单点更新+区间询问+区间合并)
- 经典问题:不断更新查找区间连续递增序列(区间合并模板+单点更新)(3308)
- hiho 1333 : 平衡树 splay 区间删除,更新,查询,单点插入
- scu 2057 树状数组 单点更新区间求和问题
- HDU 1754 I Hate It(简单线段树-单点更新,区间询问)
- BNU Watermelon Full of Water-单点更新,区间询问
- Splay解决区间问题[区间切割,区间翻转]
- CodeForce 356A Knight Tournament(线段树的区间更新+单点询问)
- 单点更新区间求和贴海报问题 hdu2795 billbord
- HDU-1754 I Hate It (线段树裸题 splay模板 单点修改 区间询问最大值)
- SPOJ GSS1 && GSS3 (无更新/更新单点,并询问区间最大连续和)
- codeforces 315 B.Sereja and Array(线段树区间更新+单点更新+单点询问)
- hdu1890 Robotic Sort (splay+区间翻转单点更新)
- poj 3468 A Simple Problem with Integers 区间更新与询问 Splay简单应用
- ZOJ 3453 Doraemon's Sweet Bullet(线段树区间更新+单点更新+最值询问)
- HDU 1556 Color the ball (树状数组-- 区间更新,单点求值)
- HDU1556 Color the ball 树状数组(区间更新单点求值)
- svn更新代码的时候出现cleanup的问题,网上找到了答案,我是解决了,不知道其他版本适不适用!!!
- HDU 3308 LCIS(区间合并 + 单点更新)