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 }
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 }
模板如下:
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;}