标签:style class blog code http tar
新学的,其实吧,就那么回事....
看了几天,splay处理序列问题,真的非常厉害,翻转,插入,删除,线段树实现不了的功能,splay用起来很方便。
这题基本就是检验模板的题,各种操作都有,错了好多次,发现以前写的代码有错了的,数据水点,给水过了,注意pushup。
Splay模板
#include <cstdio> #include <cstring> #include <map> #include <algorithm> #include <iostream> using namespace std; #define N 500000 #define INF 0x7FFFFFFF #define keyTree (ch[ ch[root][1] ][0]) int pre[N]; int lz[N]; int rev[N]; int ch[N][2]; int val[N]; int minz[N]; int sz[N]; int num[N]; int root,t; void pushup(int x) { minz[x] = min(val[x],min(minz[ch[x][0]],minz[ch[x][1]])); sz[x] = sz[ch[x][0]] + sz[ch[x][1]] + 1; } void Update_Rev(int x) { if(!x) return ; swap(ch[x][1],ch[x][0]); rev[x] ^= 1; } void Update_Add(int x,int d) { if(!x) return ; val[x] += d; minz[x] += d; lz[x] += d; } void pushdown(int x) { if(lz[x]) { Update_Add(ch[x][0],lz[x]); Update_Add(ch[x][1],lz[x]); lz[x] = 0; } if(rev[x]) { Update_Rev(ch[x][0]); Update_Rev(ch[x][1]); rev[x] = 0; } } void NewNode(int &x,int c) { x = ++t; ch[x][0] = ch[x][1] = 0; sz[x] = 1; lz[x] = rev[x] = 0; minz[x] = val[x] = c; } void makeTree(int &x,int l,int r,int rt) { if(l > r) return ; int m; 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] = rt; pushup(x); } void Rotate(int x,int flag)//左旋 右旋 { int y = pre[x]; pushdown(y); pushdown(x); ch[y][!flag] = ch[x][flag]; pre[ch[x][flag]] = y; pre[x] = pre[y]; if(pre[x]) ch[pre[y]][ ch[pre[y]][1] == y] = x; ch[x][flag] = y; pre[y] = x; pushup(y); } void splay(int x,int goal)//把x转到goal下面 { int y,z,flag; while(pre[x] != goal) { if(pre[pre[x]] == goal) { pushdown(pre[x]); pushdown(x); Rotate(x,ch[pre[x]][0] == x); } else { y = pre[x]; z = pre[y]; pushdown(z); pushdown(y); pushdown(x); flag = (ch[z][0] == y); if(ch[y][flag] == x) { Rotate(x,!flag); Rotate(x,flag); } else { Rotate(y,flag); Rotate(x,flag); } } } pushup(x); if(goal == 0) root = x; } void RotateTo(int k,int goal)//将第k个,转到goal下面 { int x = root; pushdown(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]; } pushdown(x); } splay(x,goal); } void init(int n) { root = t = 0; ch[0][0] = ch[0][1] = lz[0] = pre[0] = 0; val[0] = minz[0] = 0; rev[0] = sz[0] = 0;//初始化 NewNode(root,-1); NewNode(ch[root][1],-1); pre[t] = root; int i; for(i = 0; i < n; i ++) { scanf("%d",&num[i]); } makeTree(keyTree,0,n-1,ch[root][1]);//建树 pushup(ch[root][1]); pushup(root); } int main() { int n,i,x,y,d,m; char str[101]; scanf("%d",&n); init(n); scanf("%d",&m); for(i = 0; i < m; i ++) { scanf("%s",str); if(strcmp(str,"ADD") == 0) { scanf("%d%d%d",&x,&y,&d); RotateTo(x-1,0); RotateTo(y+1,root); Update_Add(keyTree,d); pushup(ch[root][1]); pushup(root); } else if(strcmp(str,"INSERT") == 0)//插入 { scanf("%d%d",&x,&y); RotateTo(x,0); RotateTo(x+1,root); NewNode(keyTree,y); pre[keyTree] = ch[root][1]; pushup(ch[root][1]); pushup(root); } else if(strcmp(str,"DELETE") == 0)//删除 { scanf("%d",&x); RotateTo(x-1,0); RotateTo(x+1,root); pre[keyTree] = 0; keyTree = 0; pushup(ch[root][1]); pushup(root); } else if(strcmp(str,"MIN") == 0)//最值 { scanf("%d%d",&x,&y); RotateTo(x-1,0); RotateTo(y+1,root); printf("%d\n",minz[keyTree]); } else if(strcmp(str,"REVOLVE") == 0)//右移t位 { int t,temp; scanf("%d%d%d",&x,&y,&t); if(x > y) swap(x,y); t = t%(y-x+1); if(t < 0) t += (y-x+1); if(t == 0) continue; RotateTo(y-t,0); RotateTo(y+1,root); temp = keyTree; keyTree = 0; RotateTo(x-1,0); RotateTo(x,root); keyTree = temp; pre[keyTree] = ch[root][1]; pushup(ch[root][1]); pushup(root); } else { scanf("%d%d",&x,&y);//翻转区间 if(x > y) swap(x,y); RotateTo(x-1,0); RotateTo(y+1,root); Update_Rev(keyTree); pushup(ch[root][1]); pushup(root); } } return 0; }
标签:style class blog code http tar
原文地址:http://www.cnblogs.com/naix-x/p/3784227.html