splay2(区间修改+内存回收)

poj3580

要求写一种数据结构;

对一个序列进行

区间增减(add); 区间翻转(reverse);  区间移动(revolve);

插入(insert);   删除(delete);          求区间最小值(min);

据说各种方法都可以做,但是只学了splay;

对于(revolve)是指,将区间[x,y]旋转t次

{1,2,3,4,5}   revolve(2,4,2);    {1,2,3,4,5}->{1,4,2,3,5}->{1,3,2,4,5}

PS:小常数rotate & splay操作(zuo si)

1 void small_const_rotate(int x,int d){
2   int y=T[x].fa;
3   T[y].son[!d]=T[x].son[d];
4   T[T[x].son[d]].fa=y;
5   if(T[y].fa) T[T[y].fa].son[T[T[y].fa].son[1]==y]=x;
6   T[x].fa=T[y].fa,T[x].son[d]=y;
7   T[y].fa=x;
8   up(y);
9 }
small_const_rotate
 1 void small_const_splay(int x,int goal){//伸展操作,将x调整到goal下面
 2   lazy(x);
 3   while(T[x].fa!=goal){
 4     if(T[T[x].fa].fa==goal){
 5       lazy(T[x].fa),lazy(x);
 6       rotate(x,T[T[x].fa].son[0]==x);//这题有反转操作,需要先lazy,在判断左右孩子
 7     }
 8     else{
 9       lazy(T[T[x].fa].fa),lazy(T[x].fa),lazy(x);//这题有反转操作,需要先lazy,在判断左右孩子
10       int y=T[x].fa , k=(T[T[y].fa].son[0]==y);
11       if(T[y].son[k]==x)rotate(x,k^1),rotate(x,k);//两个方向不同,则先左旋再右旋
12       else              rotate(y,k),rotate(x,k);  //两个方向相同,相同方向连续两次
13     }
14   }
15   up(x);
16   if(goal==0) root=x;
17 }
small_const_splay

 模板如下:

  1 #include <algorithm>
  2 #include <iostream>
  3 #include <cstring>
  4 #include <cstdlib>
  5 #include <cstdio>
  6 #include <vector>
  7 #include <cmath>
  8 #include <queue>
  9 #include <map>
 10 #include <set>
 11 using namespace std;
 12 #define file(x) freopen(x".in","r",stdin),freopen(x".out","w",stdout)
 13 #define Front T[T[root].son[1]].son[0]
 14 #define ls T[x].son[0]
 15 #define rs T[x].son[1]
 16 const int MAXN=100000+10;
 17 const int INF=(int)2e9;
 18 int a[MAXN],n,m;
 19 struct splay_tree{
 20   struct Node{
 21     int son[2],fa,key,size,add,rev,min;
 22     void init(){
 23       son[0]=son[1]=fa=key=size=add=rev=0;
 24       min=INF;
 25     }
 26   }T[MAXN];
 27   int root,tot,s[MAXN],top;//内存池、内存池容量
 28 
 29   void NewNode(int &x,int fa,int key){
 30     if(top)x=s[top--];
 31     else    x=++tot;
 32     ls=rs=0;
 33     T[x].fa=fa,T[x].size=1;
 34     T[x].add=T[x].rev=0;
 35     T[x].key=T[x].min=key;
 36   }
 37 
 38   void up_rev(int x){
 39     if(x==0)return;
 40     swap(ls,rs);
 41     T[x].rev^=1;
 42   }
 43 
 44   void up_add(int x,int val){
 45     if(x==0)return;
 46     T[x].add+=val, T[x].key+=val, T[x].min+=val;
 47   }
 48 
 49   void up(int x){
 50     T[x].size=T[ls].size+T[rs].size+1;
 51     T[x].min=T[x].key;
 52     if(ls)T[x].min=min(T[x].min,T[ls].min);
 53     if(rs)T[x].min=min(T[x].min,T[rs].min);
 54   }
 55 
 56   void lazy(int x){
 57     if(T[x].rev){
 58       up_rev(ls); up_rev(rs);
 59       T[x].rev=0;
 60     }
 61     if(T[x].add){
 62       up_add(ls,T[x].add); 
 63       up_add(rs,T[x].add);
 64       T[x].add=0;
 65     }
 66   }
 67 
 68   void build(int &x,int l,int r,int fa){
 69     if(l>r)return;
 70     int mid=(l+r)>>1;
 71     NewNode(x,fa,a[mid]);
 72     build(ls,l,mid-1,x);
 73     build(rs,mid+1,r,x);
 74     up(x);
 75   }
 76 
 77   void init(){
 78     root=tot=top=0;
 79     T[root].init();
 80     NewNode(root,0,INF);
 81     NewNode(T[root].son[1],root,INF);
 82     build(Front,1,n,T[root].son[1]);
 83     up(T[root].son[1]);
 84     up(root);
 85   }
 86 
 87   void rotate(int x,int k){
 88     int y=T[x].fa,z=T[y].fa;
 89     T[y].son[k^1]=T[x].son[k] ,T[T[x].son[k]].fa=y;
 90     T[x].son[k]=y ,T[y].fa=x;
 91     T[z].son[T[z].son[1]==y]=x ,T[x].fa=z;
 92     up(y);
 93   }
 94 
 95   void splay(int x,int goal){
 96     if(x==goal)return;
 97     while(T[x].fa!=goal){
 98       int y=T[x].fa,z=T[y].fa;
 99       lazy(z),lazy(y),lazy(x);
100       int rx=T[y].son[0]==x ,ry=T[z].son[0]==y;
101       if(z==goal)rotate(x,rx);
102       else{
103         if(rx==ry)rotate(y,ry);
104         else      rotate(x,rx);
105         rotate(x,ry);
106       }
107     }
108     up(x);
109     if(goal==0)root=x;
110   }
111 
112   int kth(int x,int k){
113     lazy(x);
114     int s=T[ls].size+1;
115     if(s==k)return x;
116     if(s>k)return kth(ls,k);
117     else   return kth(rs,k-s);
118   }
119 
120   void erase(int x){
121     if(x){
122       s[++top]=x;
123       erase(ls);
124       erase(rs);
125     }
126   }
127 
128   void update_add(int l,int r,int val){
129     splay(kth(root,l),0);
130     splay(kth(root,r+2),root);
131     up_add(Front,val);
132     up(T[root].son[1]);
133     up(root);
134   }
135 
136   void update_reverse(int l,int r){
137     splay(kth(root,l),0);
138     splay(kth(root,r+2),root);
139     up_rev(Front);
140     up(T[root].son[1]);
141     up(root);
142   }
143 
144   void update_revolve(int l,int r,int t){
145     int len=r-l+1; t=(t%len+len)%len;if(t==0) return;
146     int k=r-t+1;
147     splay(kth(root,k),0);
148     splay(kth(root,r+2),root);
149     int tmp=Front;
150     Front=0;
151     up(T[root].son[1]);
152     up(root);
153     splay(kth(root,l),0);
154     splay(kth(root,l+1),root);
155     Front=tmp;
156     T[Front].fa=T[root].son[1];
157     up(T[root].son[1]);
158     up(root);
159   }
160 
161   void update_insert(int x,int P){
162     splay(kth(root,x+1),0);
163     splay(kth(root,x+2),root);
164     NewNode(Front,T[root].son[1],P);
165     up(T[root].son[1]);
166     up(root);
167   }
168 
169   void update_delete(int x){
170     splay(kth(root,x),0);
171     splay(kth(root,x+2),root);
172     erase(Front);
173     T[Front].fa=0;
174     Front=0;
175     up(T[root].son[1]);
176     up(root);
177   }
178 
179   int query_min(int l,int r){
180     splay(kth(root,l),0);
181     splay(kth(root,r+2),root);
182     return T[Front].min;
183   }
184 
185   void work(){
186     char str[10];int x,y,D,P,T;
187     scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&a[i]);
188     init();
189     for(scanf("%d",&m);m--;){
190       scanf("%s%d",str,&x);
191       if(strcmp(str,"DELETE")==0)update_delete(x);
192       else if(strcmp(str,"INSERT")==0)scanf("%d",&P),update_insert(x,P);
193       else if(strcmp(str,"ADD")==0)scanf("%d%d",&y,&D),update_add(x,y,D);
194       else if(strcmp(str,"REVERSE")==0)scanf("%d",&y),update_reverse(x,y);
195       else if(strcmp(str,"MIN")==0)scanf("%d",&y),printf("%d\n",query_min(x,y));
196       else if(strcmp(str,"REVOLVE")==0)scanf("%d%d",&y,&T),update_revolve(x,y,T);
197     }
198   }
199 }poj3580;
200 int main(){poj3580.work();return 0;}
poj3580
posted @ 2017-03-04 21:12  墨鳌  阅读(166)  评论(0编辑  收藏  举报