poj 3580 SuperMemo 数据结构

题意:给一堆操作,维护数列。

思路:平衡树 splay

P.S. 太恶心了……

  1 #include<iostream>
2 #include<cstring>
3 #include<cmath>
4 using namespace std;
5 #define MAXN 110004
6 #define MAXM 110000
7 struct node
8 {
9 int left,right,father;
10 int value,size,min;
11 int adt;
12 bool rev;
13 };
14 int INF=987654321;
15 int top=0;
16 int n,m;
17 node tree[MAXN+MAXM];
18 int tmp[MAXN];
19 int root;
20 void update(int x)
21 {
22 if(x!=0)
23 {
24 tree[x].size=tree[tree[x].left].size+tree[tree[x].right].size+1;
25 tree[x].min=min(tree[tree[x].left].min,tree[tree[x].right].min);
26 tree[x].min=min(tree[x].min,tree[x].value);
27 }
28 }
29 void newnode(int lnum,int rnum,int value)
30 {
31 tree[++top].left=lnum; tree[top].right=rnum;
32 tree[top].value=value;
33 update(top);
34 tree[rnum].father=tree[lnum].father=top;
35 }
36 int build_tree(int l,int r)
37 {
38 if(l>r) return 0;
39 int mid=(l+r)/2;
40 int lnum=build_tree(l,mid-1);
41 int rnum=build_tree(mid+1,r);
42 newnode(lnum,rnum,tmp[mid]);
43 return top;
44 }
45 void pushdown(int x)
46 {
47 if(x!=0&&tree[x].rev)
48 {
49 swap(tree[x].left,tree[x].right);
50 tree[tree[x].left].rev=!tree[tree[x].left].rev;
51 tree[tree[x].right].rev=!tree[tree[x].right].rev;
52 tree[x].rev=false;
53 }
54 if(x!=0&&tree[x].adt!=0)
55 {
56 tree[tree[x].left].adt+=tree[x].adt;
57 tree[tree[x].right].adt+=tree[x].adt;
58 if(tree[x].left!=0)
59 tree[tree[x].left].min+=tree[x].adt;
60 if(tree[x].right!=0)
61 tree[tree[x].right].min+=tree[x].adt;
62 tree[tree[x].left].value+=tree[x].adt;
63 tree[tree[x].right].value+=tree[x].adt;
64 tree[x].adt=0;
65 }
66 }
67
68 void leftrotate(int x)
69 {
70 int y=tree[x].father;
71 int z=tree[x].left;
72 if(y==tree[tree[y].father].left) tree[tree[y].father].left=x;
73 else tree[tree[y].father].right=x;
74 tree[x].father=tree[y].father;
75 tree[x].left=y;
76 tree[y].father=x;
77 tree[y].right=z;
78 tree[z].father=y;
79 update(y); update(x);
80 }
81 void rightrotate(int x)
82 {
83 int y=tree[x].father;
84 int z=tree[x].right;
85 if(y==tree[tree[y].father].right) tree[tree[y].father].right=x;
86 else tree[tree[y].father].left=x;
87 tree[x].father=tree[y].father;
88 tree[x].right=y;
89 tree[y].father=x;
90 tree[y].left=z;
91 tree[z].father=y;
92 update(y); update(x);
93 }
94 void splay(int rootnew,int x)
95 {
96 pushdown(x);
97 int y,z;
98 int i=0;
99 int fa=tree[rootnew].father;
100 while(tree[x].father!=fa)
101 {
102 y=tree[x].father;
103 z=tree[y].father;
104 if(z==fa)
105 {
106 if(tree[y].left==x) rightrotate(x);
107 else leftrotate(x);
108 break;
109 }
110 if(tree[z].left==y)
111 {
112 if(tree[y].left==x) {rightrotate(y),rightrotate(x);}
113 else leftrotate(x),rightrotate(x);
114 }
115 else
116 {
117 if(tree[y].left==x) rightrotate(x),leftrotate(x);
118 else leftrotate(y),leftrotate(x);
119 }
120 }
121 if(rootnew==root)
122 root=x;
123 }
124 void find(int root,int pos)
125 {
126 int x=root;
127 while(pushdown(x),tree[tree[x].left].size+1!=pos)
128 {
129 if(tree[tree[x].left].size>=pos) x=tree[x].left;
130 else
131 pos-=tree[tree[x].left].size+1, x=tree[x].right;
132 }
133 splay(root,x);
134 }
135 void add(int l,int r,int z)
136 {
137 find(root,l);
138 find(tree[root].right,r-l);
139 int p=tree[tree[root].right].left;
140 tree[p].adt+=z; tree[p].value+=z; tree[p].min+=z;
141 splay(root,p);
142 }
143 void reverse(int l,int r)
144 {
145 find(root,l);
146 find(tree[root].right,r-l);
147 int p=tree[tree[root].right].left;
148 tree[p].rev=!tree[p].rev;
149 }
150 void revolve(int l,int r,int a)
151 {
152 find(root,l);
153 find(tree[root].right,r-l);
154 find(tree[tree[root].right].left,tree[tree[tree[root].right].left].size-a);
155 find(tree[tree[tree[root].right].left].right,tree[tree[tree[tree[root].right].left].right].size);
156 int p=tree[tree[root].right].left;
157 int t=tree[tree[tree[root].right].left].right;
158 tree[p].right=0;
159 tree[tree[p].father].left=t; tree[t].father=tree[p].father;
160 tree[t].right=p; tree[p].father=t;
161 update(p);
162 splay(root,p);
163 }
164 void insert(int pos,int value)
165 {
166 find(root,pos);
167 find(tree[root].right,1);
168 newnode(0,0,value);
169 int p=tree[root].right;
170 tree[p].left=top;
171 tree[top].father=p;
172 splay(root,top);
173 }
174 void del(int pos)
175 {
176 find(root,pos);
177 find(tree[root].left,tree[tree[root].left].size);
178 tree[tree[root].left].right=tree[root].right;
179 tree[tree[root].right].father=tree[root].left;
180 root=tree[root].left;
181 tree[root].father=0;
182 update(root);
183 }
184 int MIN(int l,int r)
185 {
186 find(root,l); find(tree[root].right,r-l);
187 int p=tree[tree[root].right].left;
188 return tree[p].min;
189 }
190
191 int main()
192 {
193 scanf("%d",&n);
194 int i;
195 int x,y,z;
196 memset(tree,0,sizeof(tree));
197 tree[0].min=INF; tree[0].size=0; tmp[1]=INF;
198 for(i=2;i<=n+1;i++) scanf("%d",tmp+i);
199 tmp[n+2]=INF;
200 root=build_tree(1,n+2); tree[root].father=0;
201 scanf("%d",&m);
202 char c[20];
203 for(i=1;i<=m;i++)
204 {
205 scanf("%s",c);
206 if(strcmp(c,"ADD")==0)
207 {
208 scanf("%d%d%d",&x,&y,&z); add(x,y+2,z);
209 }
210 if(strcmp(c,"REVERSE")==0)
211 {
212 scanf("%d%d",&x,&y); reverse(x,y+2);
213 }
214 if(strcmp(c,"REVOLVE")==0)
215 {
216 scanf("%d%d%d",&x,&y,&z);
217 if(z%(y-x+1))
218 revolve(x,y+2,z%(y-x+1));
219 }
220 if(strcmp(c,"INSERT")==0)
221 {
222 scanf("%d%d",&x,&y);
223 insert(x+1,y);
224 }
225 if(strcmp(c,"DELETE")==0)
226 {
227 scanf("%d",&x); del(x+1);
228 }
229 if(strcmp(c,"MIN")==0)
230 {
231 scanf("%d%d",&x,&y); printf("%d\n",MIN(x,y+2));
232 }
233 }
234 return 0;
235 }
原文地址:https://www.cnblogs.com/myoi/p/2350109.html