首页 > 代码库 > hdu 3436

hdu 3436

 

一开始,直接无脑的对n数组维护。打完之后一看n的范围,默默的删了。

 

一看范围,就知道要先读进来询问,把涉及到的x做一个统计,这样n的数组

1,2,...,n

(1,x0-1),x0,(x0+1,x1),x1,...,n

这样子就缩好了(一个节点是一个区间)。记录每个节点的起始数。

统计的信息,区间和(即数的个数)。

这样三个操作都能写啦。

 

  1 #include <iostream>  2 #include <cstdio>  3 #include <cstring>  4 #include <algorithm>  5 #include <map>  6 #include <set>  7   8 #define KT ch[ch[root][1]][0]  9 #define LC ch[x][0] 10 #define RC ch[x][1] 11 #define N 310001 12 using namespace std; 13  14 struct node{ 15     char op[10]; 16     int x; 17     void in(){ 18         scanf("%s%d",op,&x); 19     } 20 }; 21 struct SplayTree{ 22     int root; 23     int fa[N]; 24     int ch[N][2]; 25     int sz[N]; 26     int top1; 27     int top2; 28     int ss[N]; 29     int que[N]; 30  31     void pushdown(int x){ 32  33     } 34     void pushup(int x){ 35         sz[x]=1+sz[LC]+sz[RC]; 36         sum[x]=val[x]+sum[LC]+sum[RC]; 37     } 38     void rotate(int x,bool f){ 39         int y=fa[x]; 40         int z=fa[y]; 41         pushdown(y); 42         pushdown(x); 43         ch[y][!f]=ch[x][f]; 44         fa[ch[x][f]]=y; 45         fa[x]=z; 46         if (z) { 47             ch[z][ch[z][1]==y] = x; 48         } 49         ch[x][f] = y; 50         fa[y]=x; 51         pushup(y); 52     } 53     void splay(int x, int g) { 54         int y = fa[x]; 55         pushdown(x); 56         while(y!=g){ 57             int z= fa[y]; 58             bool f = (ch[y][0]==x); 59             if(z != g && f == (ch[z][0]==y)){ 60                 rotate(y,f); 61             } 62             rotate(x,f); 63             y=fa[x]; 64         } 65         pushup(x); 66         if(g==0) root = x; 67     } 68     void rotateTo(int k,int g) { 69         int x=root; 70         pushdown(x); 71         while(sz[LC] != k){ 72             if(k<sz[LC]){ 73                 x=LC; 74             }else{ 75                 k -= sz[LC] + 1; 76                 x = RC; 77             } 78             pushdown(x); 79         } 80         splay(x,g); 81     } 82     void build(int l,int r,int f){ 83         if(l>r){ 84             return ; 85         } 86         int x = (l + r) >> 1; 87         LC = (x - 1 >= l)? (x - 1 + l)>> 1 :0; 88         RC = (r >= x + 1)? (x + 1 + r)>> 1 :0; 89         fa[x] = f; 90         build(l,x - 1,x); 91         build(x + 1,r,x); 92         pushup(x); 93     } 94     void erase(int x){ 95         if(x==0) 96             return; 97         int father= fa[x]; 98         int head = 0, tail=0; 99         for(que[tail++] =x ; head < tail; head++){100             ss[top2++] = que[head];101             if(ch[que[head]][0]){102                 que[tail++]=ch[que[head]][0];103             }104             if(ch[que[head]][1]){105                 que[tail++] = ch[que[head]][1];106             }107         }108         ch[father][ch[father][1]==x]=0;109         pushup(father);110     }111     void treaval(int x){112         if (x) {113             pushdown(x);114             treaval(LC);115             printf("@%d",val[x]);116             //ans[cnt++]=val[x];117             treaval(RC);118         }119     }120     void newNode(int &x,int c,int r,int st){121         if(top2){122             x = ss[--top2];123         } else {124             x = ++top1;125         }126         LC = RC = fa[x] =0;127         sz[x] = 1;128         val[x] = c;129         ret[x] = r;130         start[x]=st;131 132         if(r&&pos.find(r)==pos.end()){133             pos[r]=x;134         }135 136     }137     void makeTree(int &x, int l, int r, int f){138         if(l > r){139             return;140         }141         int m=(l+r)>>1;142 143         newNode(x, num[m], m%2?a[m/2]:0,b[m]);144         makeTree(LC,l,m-1,x);145         makeTree(RC,m+1,r,x);146         fa[x]=f;147         pushup(x);148     }149     void debug(){150         treaval(root);151         cout<<endl;152     }153     void cutTo(int l,int r,int c){154         rotateTo(l-1,0);155         rotateTo(r+1,root);156         //debug();157         int tmp=KT;158         KT=0;159         pushup(ch[root][1]);160         pushup(root);161         rotateTo(c,0);162         rotateTo(c+1,root);163         fa[tmp]=ch[root][1];164         KT=tmp;165         pushup(ch[root][1]);166         pushup(root);167         //debug();168     }169     int find(int x,int k){170         if(sum[LC]<=k-1&&sum[LC]+val[x]>=k){171             return start[x]+k-sum[LC]-1;172         }173         else if(sum[LC]>=k){174             return find(LC,k);175         }else {176             return find(RC,k-sum[LC]-val[x]);177         }178     }179     void init(int n,int m){180         pos.clear();181         top1=top2=root=0;182         newNode(root,0,0,0);183         newNode(ch[root][1],0,0,0);184         fa[ch[root][1]]=root;185         for(int i=0;i<m;i++)186         {187             Q[i].in();188             aa[i]=Q[i].x;189         }190         sort(aa,aa+m);191         a[0]=aa[0];192         int cnt=1;193         for(int i=1;i<m;i++){194             if(aa[i]!=aa[i-1])195                 a[cnt++]=aa[i];196         }197         m=cnt;198         num[0]=a[0]-1;199         b[0]=1;200         for(int i=0;i<m;i++){201             if(i!=0){202                 num[i*2]=a[i]-a[i-1]-1;203                 b[i*2]=a[i-1]+1;204             }205             num[i*2+1]=1;206             b[i*2+1]=a[i];207         }208         num[m*2]=n-a[m-1];209         b[m*2]=a[m-1]+1;210         makeTree(KT,0,2*m,ch[root][1]);211         pushup(ch[root][1]);212         pushup(root);213     }214     void top(int v){215         int x=pos[v];216         splay(x,0);217         int k=sz[ch[root][0]];218 219         cutTo(k,k,0);220     }221     int rank(int k){222 223         return find(root,k);224     }225     int query(int v){226         int x=pos[v];227         splay(x,0);228         //debug();229         return sum[LC]+1;230     }231     void solve(int m){232 233         int v;234         for(int i=0;i<m;i++){235            // debug();236             v=Q[i].x;237             if(Q[i].op[0]==T){238                 top(v);239             }else if(Q[i].op[0]==R){240                 printf("%d\n",rank(v));241             }else{242                 printf("%d\n",query(v));243             }244         }245     }246     int val[N];//数值247     int sum[N];248     int ret[N];//结果249     int start[N];//该区间开始的数;250 251     int aa[N];252     int a[N];253     int b[N];254     int num[N];255     //int pos[N];256     map<int,int>pos;257     node Q[N];258 }spt;259 260 int main()261 {262     int T;263     cin>>T;264     int n,m;265     int cas=1;266     while(T--){267         scanf("%d%d",&n,&m);268         printf("Case %d:\n",cas++);269         spt.init(n,m);270         spt.solve(m);271     }272     return 0;273 }
View Code

 

hdu 3436