板子题,正在努力看懂板子。。
http://blog.csdn.net/acm_cxlove/article/details/7815019
http://www.cnblogs.com/kuangbin/archive/2013/04/21/3034081.html
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 #define keyTree (ch[ ch[root][1] ][0]) 6 #define LL long long 7 8 using namespace std; 9 10 const int maxn = 222222; 11 12 struct SpalyTree{ 13 int sz[maxn]; 14 int ch[maxn][2]; 15 int pre[maxn]; 16 int root,top1,top2; 17 int ss[maxn], que[maxn]; 18 19 void Rotate(int x,int f) 20 { 21 int y = pre[x]; 22 push_down(y); 23 push_down(x); 24 ch[y][!f] = ch[x][f]; 25 pre[ ch[x][f]] = y; 26 pre[x] = pre[y]; 27 if(pre[x]) ch[pre[y] ][ch[pre[y]][1]==y ] = x; 28 ch[x][f] = y; 29 pre[y] = x; 30 push_up(y); 31 } 32 void Splay(int x,int goal) 33 { 34 push_down(x); 35 while(pre[x] != goal) 36 { 37 if(pre[pre[x] ] == goal) 38 { 39 Rotate(x,ch[pre[x] ][0] == x); 40 } 41 else 42 { 43 int y = pre[x],z = pre[y]; 44 int f = (ch[z][0] == y); 45 if(ch[y][f] == x) 46 { 47 Rotate(x,!f),Rotate(x,f); 48 } 49 else 50 { 51 Rotate(y,f),Rotate(x,f); 52 } 53 } 54 } 55 push_up(x); 56 if(goal == 0) root = x; 57 } 58 void RotateTo(int k,int goal) 59 { 60 int x = root; 61 push_down(x); 62 while(sz[ ch[x][0] ] != k) 63 { 64 if(k < sz[ ch[x][0] ]) 65 { 66 x = ch[x][0]; 67 } 68 else 69 { 70 k -= (sz[ch[x][0] ] + 1); 71 x = ch[x][1]; 72 } 73 push_down(x); 74 } 75 Splay(x,goal); 76 } 77 void erase(int x) 78 { 79 int father = pre[x]; 80 int head = 0,tail = 0; 81 for(que[tail++] = x;head < tail;head++) 82 { 83 ss[top2++] = que[head]; 84 if(ch[que[head] ][0]) que[tail++] = ch[que[head] ][0]; 85 if(ch[que[head] ][1]) que[tail++] = ch[que[head] ][1]; 86 } 87 ch[father ][ch[father][1]==x ] = 0; 88 push_up(father); 89 } 90 void debug(){printf("%d ",root);Treaval(root);} 91 void Treaval(int x) 92 { 93 if(x) 94 { 95 Treaval(ch[x][0]); 96 printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d ,val = %2d ",x,ch[x][0],ch[x][1],pre[x],sz[x],val[x]); 97 Treaval(ch[x][1]); 98 } 99 } 100 void NewNode(int &x,int c) 101 { 102 if(top2) x = ss[--top2]; 103 else x = ++top1; 104 ch[x][0] = ch[x][1] = pre[x] = 0; 105 sz[x] = 1; 106 107 val[x] = sum[x] = c; 108 add[x] = 0; 109 } 110 void push_down(int x) 111 { 112 if(add[x]) 113 { 114 val[x] += add[x]; 115 add[ch[x][0] ] += add[x]; 116 add[ch[x][1] ] += add[x]; 117 sum[ch[x][0] ] += (LL)sz[ch[x][0] ]*add[x]; 118 sum[ch[x][1] ] += (LL)sz[ch[x][1] ]*add[x]; 119 add[x] = 0; 120 } 121 } 122 void push_up(int x) 123 { 124 sz[x] = 1+sz[ch[x][0] ] + sz[ch[x][1] ]; 125 sum[x] = add[x] + val[x] + sum[ch[x][0] ] + sum[ch[x][1] ]; 126 } 127 void makeTree(int &x,int l,int r,int f) 128 { 129 if(l > r) return ; 130 int m = (l+r)>>1; 131 NewNode(x,num[m]); 132 makeTree(ch[x][0],l,m-1,x); 133 makeTree(ch[x][1],m+1,r,x); 134 pre[x] = f; 135 push_up(x); 136 } 137 void init(int n) 138 { 139 ch[0][0] = ch[0][1] = pre[0] = sz[0] = 0; 140 add[0] = sum[0] = 0; 141 142 root = top1 = 0; 143 NewNode(root, -1); 144 NewNode(ch[root][1],-1); 145 pre[top1] = root; 146 sz[root] = 2; 147 148 for(int i=0;i<n;i++) 149 scanf("%d",&num[i]); 150 makeTree(keyTree,0,n-1,ch[root][1]); 151 push_up(ch[root][1]); 152 push_up(root); 153 } 154 void update() 155 { 156 int l,r,c; 157 scanf("%d%d%d",&l,&r,&c); 158 RotateTo(l-1,0); 159 RotateTo(r+1,root); 160 add[keyTree] += c; 161 sum[keyTree] += (LL)c*sz[keyTree]; 162 } 163 void query() 164 { 165 int l,r; 166 scanf("%d%d",&l,&r); 167 RotateTo(l-1,0); 168 RotateTo(r+1,root); 169 printf("%lld ",sum[keyTree]); 170 } 171 172 int num[maxn]; 173 int val[maxn]; 174 int add[maxn]; 175 LL sum[maxn]; 176 }spt; 177 178 int n,m; 179 180 int main() 181 { 182 while(~scanf("%d%d",&n,&m)) 183 { 184 spt.init(n); 185 char op[2]; 186 for(int i=0;i<m;i++) 187 { 188 scanf("%s",op); 189 if(op[0] == 'Q') 190 { 191 spt.query(); 192 } 193 else 194 spt.update(); 195 } 196 } 197 }