POJ3468/splay树/成段更新
2016-05-14 17:54
295 查看
板子题,正在努力看懂板子。。
http://blog.csdn.net/acm_cxlove/article/details/7815019
http://www.cnblogs.com/kuangbin/archive/2013/04/21/3034081.html
http://blog.csdn.net/acm_cxlove/article/details/7815019
http://www.cnblogs.com/kuangbin/archive/2013/04/21/3034081.html
#include <cstdio> #include <cstring> #include <algorithm> #define keyTree (ch[ ch[root][1] ][0]) #define LL long long using namespace std; const int maxn = 222222; struct SpalyTree{ int sz[maxn]; int ch[maxn][2]; int pre[maxn]; int root,top1,top2; int ss[maxn], que[maxn]; void Rotate(int x,int f) { int y = pre[x]; push_down(y); push_down(x); ch[y][!f] = ch[x][f]; pre[ ch[x][f]] = y; pre[x] = pre[y]; if(pre[x]) ch[pre[y] ][ch[pre[y]][1]==y ] = x; ch[x][f] = y; pre[y] = x; push_up(y); } void Splay(int x,int goal) { push_down(x); while(pre[x] != goal) { if(pre[pre[x] ] == goal) { Rotate(x,ch[pre[x] ][0] == x); } else { int y = pre[x],z = pre[y]; int f = (ch[z][0] == y); if(ch[y][f] == x) { Rotate(x,!f),Rotate(x,f); } else { Rotate(y,f),Rotate(x,f); } } } push_up(x); if(goal == 0) root = x; } void RotateTo(int k,int goal) { int x = root; push_down(x); while(sz[ ch[x][0] ] != k) { if(k < sz[ ch[x][0] ]) { x = ch[x][0]; } else { k -= (sz[ch[x][0] ] + 1); x = ch[x][1]; } push_down(x); } Splay(x,goal); } void erase(int x) { int father = pre[x]; int head = 0,tail = 0; for(que[tail++] = x;head < tail;head++) { ss[top2++] = que[head]; if(ch[que[head] ][0]) que[tail++] = ch[que[head] ][0]; if(ch[que[head] ][1]) que[tail++] = ch[que[head] ][1]; } ch[father ][ch[father][1]==x ] = 0; push_up(father); } void debug(){printf("%d\n",root);Treaval(root);} void Treaval(int x) { if(x) { Treaval(ch[x][0]); printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d ,val = %2d\n",x,ch[x][0],ch[x][1],pre[x],sz[x],val[x]); Treaval(ch[x][1]); } } void NewNode(int &x,int c) { if(top2) x = ss[--top2]; else x = ++top1; ch[x][0] = ch[x][1] = pre[x] = 0; sz[x] = 1; val[x] = sum[x] = c; add[x] = 0; } void push_down(int x) { if(add[x]) { val[x] += add[x]; add[ch[x][0] ] += add[x]; add[ch[x][1] ] += add[x]; sum[ch[x][0] ] += (LL)sz[ch[x][0] ]*add[x]; sum[ch[x][1] ] += (LL)sz[ch[x][1] ]*add[x]; add[x] = 0; } } void push_up(int x) { sz[x] = 1+sz[ch[x][0] ] + sz[ch[x][1] ]; sum[x] = add[x] + val[x] + sum[ch[x][0] ] + sum[ch[x][1] ]; } void makeTree(int &x,int l,int r,int f) { if(l > r) return ; int m = (l+r)>>1; NewNode(x,num[m]); makeTree(ch[x][0],l,m-1,x); makeTree(ch[x][1],m+1,r,x); pre[x] = f; push_up(x); } void init(int n) { ch[0][0] = ch[0][1] = pre[0] = sz[0] = 0; add[0] = sum[0] = 0; root = top1 = 0; NewNode(root, -1); NewNode(ch[root][1],-1); pre[top1] = root; sz[root] = 2; for(int i=0;i<n;i++) scanf("%d",&num[i]); makeTree(keyTree,0,n-1,ch[root][1]); push_up(ch[root][1]); push_up(root); } void update() { int l,r,c; scanf("%d%d%d",&l,&r,&c); RotateTo(l-1,0); RotateTo(r+1,root); add[keyTree] += c; sum[keyTree] += (LL)c*sz[keyTree]; } void query() { int l,r; scanf("%d%d",&l,&r); RotateTo(l-1,0); RotateTo(r+1,root); printf("%lld\n",sum[keyTree]); } int num[maxn]; int val[maxn]; int add[maxn]; LL sum[maxn]; }spt; int n,m; int main() { while(~scanf("%d%d",&n,&m)) { spt.init(n); char op[2]; for(int i=0;i<m;i++) { scanf("%s",op); if(op[0] == 'Q') { spt.query(); } else spt.update(); } } }
相关文章推荐
- CLR垃圾回收的设计
- Unity3d Realtime Dynamic Volume Clouds Rendering
- 源码推荐(05.14):tableViewHeader,简单的历史搜索
- MyGUI 总结1
- 第7周 C语言程序设计(新2版) 练习2-5 返回最早出现匹配字符的位置
- 2.4G WLAN芯片 AR9341 学习笔记
- matlab 常用 api(七)—— 常见判断(返回 logical)
- C++ Namespace命名空间和static的用法总结
- 深入浅出TCP/IP簇
- 回文字符串
- 阅读程序,不同定义下的结果
- c++;每周一些题(3)
- 合并两个排序的链表——17
- Android中调用系统所装的软件打开文件
- java泛型总结(一)
- csv文件导入mysql数据库命令
- 阅读程序,写结果4
- Cooperation.GTST团队第一周项目总结
- Servlet & JSP - Form-based Authentication
- js 图片预览