题意:给你一个数列,区间更新和区间询问
解题思路:splay指针版撸的,4700 ms险过
解题代码:

1 // File Name: spoj3468.cpp
2 // Author: darkdream
3 // Created Time: 2014年11月05日 星期三 19时40分26秒
4
5 #include<vector>
6 #include<list>
7 #include<map>
8 #include<set>
9 #include<deque>
10 #include<stack>
11 #include<bitset>
12 #include<algorithm>
13 #include<functional>
14 #include<numeric>
15 #include<utility>
16 #include<sstream>
17 #include<iostream>
18 #include<iomanip>
19 #include<cstdio>
20 #include<cmath>
21 #include<cstdlib>
22 #include<cstring>
23 #include<ctime>
24 #define LL long long
25 #define maxn 100010
26 using namespace std;
27 int num[maxn];
28 struct Splaynode{
29 struct node{
30 struct node *pre,*ch[2];
31 LL add;
32 LL sum;
33 LL val;
34 LL size;
35 }*root;
36 node *newnode(int c)
37 {
38 node * p = (node*)malloc(sizeof(node));
39 p->pre = p->ch[0] = p->ch[1] = NULL;
40 p->sum = p->val = c ;
41 p->size = 1 ;
42 p->add = 0 ;
43 return p ;
44 }
45 void push_down(node *x)
46 {
47 //printf("push_down***%lld\n",x->val);
48 x->val += x->add;
49 if(x->ch[0] != NULL)
50 {
51 x->ch[0]->sum += x->ch[0]->size * x->add;
52 x->ch[0]->add += x->add;
53 }
54 if(x->ch[1] != NULL)
55 {
56 x->ch[1]->sum += x->ch[1]->size * x->add;
57 x->ch[1]->add += x->add;
58 }
59 x->add = 0 ;
60 }
61 void push_up(node *x)
62 {
63 x->size = 1;
64 x->sum = x->val + x->add;
65 if(x->ch[0] != NULL)
66 {
67 x->size += x->ch[0]->size;
68 x->sum += x->ch[0]->sum;
69 }
70 if(x->ch[1] != NULL)
71 {
72 x->size += x->ch[1]->size;
73 x->sum += x->ch[1]->sum;
74 }
75 }
76 void print(node *x)
77 {
78 if(x == NULL)
79 return;
80 print(x->ch[0]);
81 printf("%lld(%lld) ",x->val,x->sum);
82 print(x->ch[1]);
83 push_up(x);
84 }
85 void build(node *&x ,int l , int r ,node *f) //这里需要传递一个引用
86 {
87 // printf("%d %d\n",l,r);
88 if(l > r )
89 return ;
90 int m = (l + r ) >> 1;
91 x = newnode(num[m]);
92 build(x->ch[0],l,m-1,x);
93 build(x->ch[1],m+1,r,x);
94 x->pre = f ;
95 push_up(x);
96 }
97 void init(int n)
98 {
99 root = NULL;
100 root = newnode(-1);
101 root->ch[1]=newnode(-1);
102 root->ch[1]->pre = root;
103 root->size = 2;
104 for(int i = 1;i <= n;i ++)
105 scanf("%d",&num[i]);
106 build(root->ch[1]->ch[0],1,n,root->ch[1]);
107 push_up(root->ch[1]);
108 push_up(root);
109 }
110 void Rotate(node *x ,int c)
111 {
112 node *y = x->pre;
113 //printf("%lld %lld\n",y->val,x->val);
114 push_down(y);
115 push_down(x);
116 y->ch[!c] = x->ch[c];
117 if(x->ch[c] != NULL) x->ch[c]->pre = y;
118 x->pre = y->pre;
119 if(y->pre != NULL)
120 {
121 if(y->pre->ch[0] == y) y->pre->ch[0] = x ;
122 else y->pre->ch[1] = x ;
123 }
124 x->ch[c] = y,y->pre = x;
125 push_up(y);
126 }
127 void Delete(node *x)
128 {
129 if(x == NULL)
130 return;
131 Delete(x->ch[0]);
132 Delete(x->ch[1]);
133 //printf("%lld\n",x->val);
134 free(x);
135 x = NULL;
136 if(x != NULL)
137 printf("****\n");
138 //x = NULL;
139 //printf("%lld\n",x->val);
140 }
141 void Splay(node *x ,node *f)
142 {
143 //printf("****\n");
144 push_down(x); //为何要push_down
145 // printf("****\n");
146 for(; x->pre != f ;)
147 if(x ->pre->pre == f)
148 {
149 if(x->pre-> ch[0] == x)
150 Rotate(x,1);
151 else Rotate(x,0);
152 }else{
153 node *y = x->pre ,*z = y ->pre;
154 if(z->ch[0] == y)
155 {
156 if(y->ch[0] == x)
157 Rotate(y,1),Rotate(x,1);
158 else Rotate(x,0),Rotate(x,1);
159 }else{
160 if(y->ch[1] == x)
161 Rotate(y,0),Rotate(x,0);
162 else
163 Rotate(x,1),Rotate(x,0);
164 }
165 }
166 push_up(x);
167 if(f == NULL) root = x;
168 }
169 void Rotateto(int k ,node *goal)
170 {
171 node *x = root;
172 push_down(x);
173 while(1)
174 {
175 if((x->ch[0] == NULL &&k == 0) || (x->ch[0]!= NULL && x->ch[0]->size == k))
176 break;
177 if(x->ch[0] !=NULL && k < x->ch[0]->size)
178 {
179 x = x->ch[0];
180 }else{
181 k -= ((!x->ch[0])?1:x->ch[0]->size+1);
182 x = x->ch[1];
183 }
184 push_down(x);
185 // printf("%lld %lld %d\n",x->val,x->size,k);
186 }
187 // printf("****\n");
188 //printf("%lld\n",x->pre->val);
189 Splay(x,goal);
190 }
191 void update()
192 {
193 int l , r, c;
194 scanf("%d %d %d",&l,&r,&c);
195 Rotateto(l-1,NULL);
196 Rotateto(r+1,root);
197 root->ch[1]->ch[0]->add += c;
198 root->ch[1]->ch[0]->sum += root->ch[1]->ch[0]->size * c;
199 }
200 void query()
201 {
202 int l , r;
203 scanf("%d %d",&l,&r);
204 Rotateto(l-1,NULL);
205 // print(root);
206 // printf("\n");
207 Rotateto(r+1,root);
208 // print(root);
209 // printf("\n");
210 // printf("****\n");
211 printf("%lld\n",root->ch[1]->ch[0]->sum);
212 }
213
214 }sp;
215
216 int main(){
217 int n ,m;
218 scanf("%d %d",&n,&m);
219 sp.init(n);
220 //sp.print(sp.root);;
221 // printf("\n");
222 while(m--)
223 {
224 char op[10];
225 scanf("%s",op);
226 if(op[0] == 'Q')
227 {
228 sp.query();
229 }else {
230 sp.update();
231 }
232 }
233 // while()
234 return 0;
235 }
常数大概是线段树的3-4倍
又用数组写了一发

1 // File Name: poj3468.sz.cpp
2 // Author: darkdream
3 // Created Time: 2014年11月07日 星期五 08时45分48秒
4
5 #include<vector>
6 #include<list>
7 #include<map>
8 #include<set>
9 #include<deque>
10 #include<stack>
11 #include<bitset>
12 #include<algorithm>
13 #include<functional>
14 #include<numeric>
15 #include<utility>
16 #include<sstream>
17 #include<iostream>
18 #include<iomanip>
19 #include<cstdio>
20 #include<cmath>
21 #include<cstdlib>
22 #include<cstring>
23 #include<ctime>
24 #define LL long long
25 #define maxn 100010
26 using namespace std;
27 #define keytree ch[ch[root][1]][0]
28 struct SplayTree{
29 int sz[maxn]; //大小
30 int ch[maxn][2]; //儿子
31 int pre[maxn]; //父亲
32 int root ,top1,top2;
33 int ss[maxn],que[maxn];
34 inline void Rotate(int x ,int f){
35 int y = pre[x];
36 push_down(y);
37 push_down(x);
38 ch[y][!f] = ch[x][f];
39 pre[ch[x][f]] = y ;
40 pre[x] = pre[y];
41 if(pre[x])
42 ch[pre[y]][ch[pre[y]][1] == y] = x;
43 ch[x][f] = y ;
44 pre[y] = x;
45 push_up(y);
46 }
47 void Splay(int x, int goal){
48 push_down(x);
49 while(pre[x] != goal){
50 if(pre[pre[x]] == goal){
51 Rotate(x,ch[pre[x]][0] == x);
52 }else{
53 int y = pre[x],z = pre[y];
54 int f = (ch[z][0] == y);
55 if(ch[y][f] == x)
56 {
57 Rotate(x,!f),Rotate(x,f);
58 }else{
59 Rotate(y,f),Rotate(x,f);
60 }
61 }
62 }
63 push_up(x);
64 if(goal == 0 ) root = x;
65 }
66 void Rotateto(int k ,int goal)
67 {
68 int x = root;
69 push_down(x);
70 while(sz[ch[x][0]] != k){
71 if(k < sz[ch[x][0]])
72 {
73 x= ch[x][0];
74 }else {
75 k -=(sz[ch[x][0]]+1);
76 x = ch[x][1];
77 }
78 push_down(x);
79 }
80 Splay(x,goal);
81 }
82 /*void erase(int x ){
83 int father = pre[x];
84 int head = 0 , tail = 0 ;
85 for()
86 }*/
87 void debug(){printf("%d\n",root);Treaval(root);}
88 void Treaval(int x) {
89 if(x) {
90 Treaval(ch[x][0]);
91 printf("结点%2d:左儿子 %2d 右儿子 %2d 父结点 %2d size = %2d ,val = %2d sum = %3lld\n",x,ch[x][0],ch[x][1],pre[x],sz[x],val[x],sum[x]);
92 Treaval(ch[x][1]);
93 }
94 }
95 void newnode(int &x,int c)
96 {
97 if(top2) x= ss[--top2];
98 else x = ++ top1;
99 ch[x][0] = ch[x][1] = pre[x] = 0 ;
100 sz[x] = 1;
101
102 val[x] = sum[x] = c;
103 add[x] = 0 ;
104 }
105 void push_down(int x){
106 if(add[x]){
107 val[x] += add[x];
108 add[ch[x][0]] += add[x];
109 add[ch[x][1]] += add[x];
110 sum[ch[x][0]] += (long long)sz[ch[x][0]] * add[x];
111 sum[ch[x][1]] += (long long)sz[ch[x][1]] * add[x];
112 add[x] = 0 ;
113 }
114 }
115 void push_up(int x){
116 sz[x] = 1 + sz[ch[x][0]] +sz[ch[x][1]];
117
118 sum[x] = add[x] + val[x] + sum[ch[x][0]] + sum[ch[x][1]];
119 }
120 void build(int &x,int l ,int r,int f)
121 {
122 if(l > r ) return;
123 int m = (l + r) >> 1;
124 newnode(x,num[m]);
125 build(ch[x][0],l,m-1,x);
126 build(ch[x][1],m+1,r,x); //这里与线段树不同,因为这个节点本身就含有信息
127 pre[x] = f;
128 push_up(x);
129 }
130 void init(int n)
131 {
132 ch[0][0] = ch[0][1] = pre[0] = sz[0] =0 ;
133 add[0] = sum[0] =0 ;
134 root = top1 = 0 ;
135 newnode(root,-1); //这里注意 root 是从1 开始的
136 //printf("%d\n",top1);
137
138 newnode(ch[root][1],-1);
139 pre[top1] = root ;
140 sz[root] = 2;
141 for(int i = 1;i <= n;i ++)
142 scanf("%d",&num[i]);
143 build(keytree,1,n,ch[root][1]);
144 push_up(ch[root][1]);
145 push_up(root);
146 }
147 void update()
148 {
149 int l , r, c;
150 scanf("%d %d %d",&l,&r,&c);
151 Rotateto(l-1,0);
152 Rotateto(r+1,root);
153 add[keytree] += c ;
154 sum[keytree] += (long long)sz[keytree] * c;
155 }
156 void query()
157 {
158 int l , r;
159 scanf("%d %d",&l,&r);
160 Rotateto(l-1,0);
161 Rotateto(r+1,root);
162 printf("%lld\n",sum[keytree]);
163 }
164 int num[maxn];
165 int val[maxn];
166 int add[maxn];
167 long long sum[maxn];
168 }sp;
169 int main(){
170 int n , m ;
171 scanf("%d %d",&n,&m);
172 sp.init(n);
173 while(m--)
174 {
175 char op[10];
176 scanf("%s",op);
177 if(op[0] == 'Q')
178 {
179 sp.query();
180 }else {
181 sp.update();
182 }
183 //sp.debug();
184 }
185 return 0;
186 }
来源:https://www.cnblogs.com/zyue/p/4080393.html
