poj 3580 SuperMemo

解法:splay显而易见

  除了REVOLVE操作,其它的都是splay的常规操作。

  REVOLVE操作可以用三次翻转操作来实现。。。如果要实现区间[a,b][b+1,c]的交换,可以依次翻转[a,b],[b+1,c],[a,b]。。。。

p.s.换了下splay的代码风格。。瞬间感觉清新明快不少。。。。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 using namespace std;
  5 const int N = (int)1e6+10;
  6 const int inf=~0u>>2;
  7 int s[N];
  8 struct splaytree{
  9     int cnt,root;
 10     int sz[N],ch[N][2],pre[N];
 11     int add[N],rev[N],minn[N],val[N];
 12     inline void newnode(int &t,int v){
 13         t=++cnt;
 14         ch[t][0]=ch[t][1]=0;
 15         add[t]=rev[t]=0;
 16         sz[t]=1;
 17         minn[t]=v;
 18         val[t]=v;
 19     }
 20     inline void pushup(int x){
 21         sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1;
 22         minn[x]=min(min(minn[ch[x][0]],minn[ch[x][1]]),val[x]);
 23     }
 24     inline void pushdown(int x){
 25         if(rev[x]){
 26             if(ch[x][0])rev[ch[x][0]]^=1;
 27             if(ch[x][1])rev[ch[x][1]]^=1;
 28             swap(ch[x][0],ch[x][1]);
 29             rev[x]^=1;
 30         }
 31         if(add[x]){
 32             if(ch[x][0])add[ch[x][0]]+=add[x],minn[ch[x][0]]+=add[x],val[ch[x][0]]+=add[x];
 33             if(ch[x][1])add[ch[x][1]]+=add[x],minn[ch[x][1]]+=add[x],val[ch[x][1]]+=add[x];
 34             add[x]=0;
 35         }
 36     }
 37     inline bool dir(int x){return ch[pre[x]][1]==x;}
 38     inline void link(int x,int y,int d){
 39         if(y)ch[y][d]=x;
 40         if(x)pre[x]=y;
 41     }
 42     inline void rotate(int x){
 43         int y=pre[x];bool d=dir(x);
 44         pushdown(y);pushdown(x);
 45         link(x,pre[y],dir(y));
 46         link(ch[x][!d],y,d);
 47         link(y,x,!d);
 48         pushup(y);
 49     }
 50     inline void splay(int x,int goal){
 51         pushdown(x);
 52         while(pre[x]!=goal){
 53             if(pre[pre[x]]==goal)rotate(x);
 54             else{
 55                 if(dir(x)==dir(pre[x]))rotate(pre[x]);
 56                 else rotate(x);
 57                 rotate(x);
 58             }
 59         }
 60         pushup(x);
 61         if(goal==0)root=x;
 62     }
 63     inline void select(int k,int goal){
 64         int x=root;
 65         pushdown(x);
 66         while(sz[ch[x][0]]!=k){
 67             if(sz[ch[x][0]] > k ) x=ch[x][0];
 68             else{
 69                 k-=(sz[ch[x][0]]+1);x=ch[x][1];
 70             }
 71             pushdown(x);
 72         }
 73         splay(x,goal);
 74     }
 75     inline int get(int L,int R){
 76         select(L-1,0);
 77         select(R+1,root);
 78         return ch[root][1];
 79     }
 80     inline void build(int l,int r,int &t,int p){
 81         if(l>r)return;
 82         int m=(l+r)>>1;
 83         newnode(t,s[m]);
 84         build(l,m-1,ch[t][0],t);
 85         build(m+1,r,ch[t][1],t);
 86         pre[t]=p;
 87         pushup(t);
 88     }
 89     void init(int n){
 90         cnt=root=0;
 91         sz[0]=ch[0][0]=ch[0][1]=pre[0]=0;
 92         add[0]=rev[0]=0;
 93         minn[0]=inf;
 94         val[0]=inf;
 95         newnode(root,inf);
 96         newnode(ch[root][1],inf);
 97         pre[cnt]=root;
 98         sz[root]=2;
 99         build(1,n,ch[ch[root][1]][0],ch[root][1]);
100         pushup(ch[root][1]);
101         pushup(root);
102     }
103     inline void ADD(int L,int R,int d){
104         int x=get(L,R);
105         add[ch[x][0]]+=d;
106         minn[ch[x][0]]+=d;
107         val[ch[x][0]]+=d;
108         pushup(x);
109         pushup(root);
110     }
111     inline void REVERSE(int L,int R){
112         int x=get(L,R);
113         rev[ch[x][0]]^=1;
114     }
115     inline void INSERT(int x,int val){
116         select(x,0);
117         select(x+1,root);
118         newnode(ch[ch[root][1]][0],val);
119         pre[ch[ch[root][1]][0]]=ch[root][1];
120         pushup(ch[root][1]);
121         pushup(root);
122     }
123     inline void REVOLVE(int L,int R,int t){
124         int len=(R-L+1);t=(t%len+len)%len;
125         if(t==0)return;
126         REVERSE(L,R-t);
127         REVERSE(R-t+1,R);
128         REVERSE(L,R);
129     }
130     inline void DELETE(int P){
131         int x=get(P,P);
132         ch[x][0]=0;
133         pushup(x);
134         pushup(root);
135     }
136     inline int MIN(int L,int R){
137         int x=get(L,R);
138         return minn[ch[x][0]];
139     }
140 };
141 splaytree a;
142 int main(){
143     int n,m,x,y,t;
144     char op[10];
145     while(~scanf("%d",&n)){
146         for(int i=1;i<=n;i++)scanf("%d",&s[i]);
147         a.init(n);
148         scanf("%d",&m);
149         while(m--){
150             scanf("%s",op);
151             if(op[0]=='A'){
152                 scanf("%d%d%d",&x,&y,&t);
153                 a.ADD(x,y,t);
154             }else if(op[0]=='R'){
155                 if(op[3]=='E'){
156                     scanf("%d%d",&x,&y);
157                     a.REVERSE(x,y);
158                 }else{
159                     scanf("%d%d%d",&x,&y,&t);
160                     a.REVOLVE(x,y,t);
161                 }
162             }else if(op[0]=='I'){
163                 scanf("%d%d",&x,&t);
164                 a.INSERT(x,t);
165             }else if(op[0]=='D'){
166                 scanf("%d",&x);
167                 a.DELETE(x);
168             }else{
169                 scanf("%d%d",&x,&y);
170                 printf("%d\n",a.MIN(x,y));
171             }
172         }
173     }
174     return 0;
175 }

 

posted @ 2013-04-18 20:59  silver__bullet  阅读(669)  评论(0编辑  收藏  举报