【bzoj 3595】: [Scoi2014]方伯伯的Oj

传送门&& 原题解

蒟蒻终于做到一道方伯伯的题了……

调了一个上午一直TLE(发现自己打了好久的splay板子竟然是错的这种丢人事情我就不说了)

很明显,要建两棵树,$T1$维护排名,$T2$维护编号,$T2$表示编号为$x$的点在$T1$中的节点编号

操作一:在$T2$中找到编号,到$T1$算排名,然后更新$T2$

其他操作类似

然后重点讲一下分点操作

因为只有$10^5$个操作,但却有$10^8$个点,所以不可能对每一个点都建树

于是我们考虑一下,让splay的每一个节点代表的不是点,而是一个区间。当需要用到点时,再把这个点从区间中分裂出来

这样可以保证不需要用到的节点不会影响复杂度

关于分点操作具体如何实现,可以参考代码

  1 //minamoto
  2 #include<bits/stdc++.h>
  3 using namespace std;
  4 const int N=330005,INF=0x3f3f3f3f;
  5 #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<15,stdin),p1==p2)?EOF:*p1++)
  6 char buf[1<<15],*p1=buf,*p2=buf;
  7 inline int read(){
  8     #define num ch-'0'
  9     char ch;bool flag=0;int res;
 10     while(!isdigit(ch=getc()))
 11     (ch=='-')&&(flag=true);
 12     for(res=num;isdigit(ch=getc());res=res*10+num);
 13     (flag)&&(res=-res);
 14     #undef num
 15     return res;
 16 }
 17 char obuf[1<<24],*o=obuf;
 18 void print(int x){
 19     if(x>9) print(x/10);
 20     *o++=x%10+48;
 21 }
 22 map<int,int> f;int n,m,ans;
 23 struct node{
 24     int fa,ch[2];
 25     int sz,l,r;
 26 } e[N];
 27 int cnt,root;
 28 void pushup(int x){
 29     e[x].sz=e[e[x].ch[0]].sz+e[e[x].ch[1]].sz+e[x].r-e[x].l+1;
 30 }
 31 void rotate(int x){
 32     int y=e[x].fa,z=e[y].fa;
 33     int op= e[y].ch[1]==x;
 34     e[x].fa=z;
 35     if(z) e[z].ch[e[z].ch[1]==y]=x;
 36     e[y].ch[op]=e[x].ch[op^1],e[e[x].ch[op^1]].fa=y;
 37     e[y].fa=x;e[x].ch[op^1]=y;
 38     pushup(x),pushup(y);
 39 }
 40 void splay(int x,int goal){
 41     while(e[x].fa!=goal){
 42         int y=e[x].fa,z=e[y].fa;
 43         if(z!=goal)
 44         ((e[z].ch[0]==y)^(e[y].ch[0]==x))?rotate(x):rotate(y);
 45         rotate(x);
 46     }
 47     pushup(x);
 48     if(goal==0) root=x;
 49 }
 50 int query(int x){
 51     splay(x,0);
 52     return e[x].sz-e[e[x].ch[1]].sz;
 53 }
 54 void pop(int x){
 55     int lower=e[x].ch[0];
 56     int upper=e[x].ch[1];
 57     while(e[lower].ch[1]) lower=e[lower].ch[1];
 58     while(e[upper].ch[0]) upper=e[upper].ch[0];
 59     if(!lower&&!upper) {root=0;return;}
 60     if(!lower){
 61         splay(upper,0);
 62         e[x].fa=e[upper].ch[0]=0;
 63         e[x].sz=1,pushup(upper);
 64     }
 65     else if(!upper){
 66         splay(lower,0);
 67         e[x].fa=e[lower].ch[1]=0;
 68         e[x].sz=1,pushup(lower);
 69     }
 70     else{
 71         splay(lower,0),splay(upper,lower);
 72         e[upper].ch[0]=e[x].fa=0;
 73         e[x].sz=1;
 74         pushup(upper),pushup(lower);
 75     }
 76 }
 77 int getKth(int x){
 78     int now=root;
 79     while(true){
 80         int sum=e[e[now].ch[0]].sz+e[now].r-e[now].l+1;
 81         if(e[e[now].ch[0]].sz>=x) now=e[now].ch[0];
 82         else if(sum>=x){x-=e[e[now].ch[0]].sz;break;}
 83         else x-=sum,now=e[now].ch[1];
 84     }
 85     return e[now].l+x-1;
 86 }
 87 void push_front(int x){
 88     if(!root){root=x;return;}
 89     int fa=root;
 90     while(e[fa].ch[0]) e[fa].sz++,fa=e[fa].ch[0];
 91     e[fa].sz++;
 92     e[fa].ch[0]=x,e[x].fa=fa;
 93     splay(x,0);
 94 }
 95 void push_back(int x){
 96     if(!root){root=x;return;}
 97     int fa=root;
 98     while(e[fa].ch[1]) e[fa].sz++,fa=e[fa].ch[1];
 99     e[fa].sz++;
100     e[fa].ch[1]=x,e[x].fa=fa;
101     splay(x,0);
102 }
103 void split(int x,int id){
104     int l=e[x].l,r=e[x].r,ls,rs;
105     if(l==r) return;
106     if(l==id){
107         rs=++cnt;
108         f[r]=rs,f[id]=x;
109         e[rs].ch[1]=e[x].ch[1];
110         e[e[rs].ch[1]].fa=rs;
111         e[x].ch[1]=rs,e[rs].fa=x;
112         e[rs].l=l+1,e[rs].r=r;
113         e[x].r=l;
114         pushup(rs),pushup(x);
115     }
116     else if(r==id){
117         ls=++cnt;
118         f[r-1]=ls,f[id]=x;
119         e[ls].ch[0]=e[x].ch[0];
120         e[e[ls].ch[0]].fa=ls;
121         e[x].ch[0]=ls,e[ls].fa=x;
122         e[ls].l=l,e[ls].r=r-1;
123         e[x].l=r;
124         pushup(ls),pushup(x);
125     }
126     else{
127         ls=++cnt,rs=++cnt;
128         f[id]=x,f[id-1]=ls,f[r]=rs;
129         e[ls].ch[0]=e[x].ch[0],e[rs].ch[1]=e[x].ch[1];
130         e[e[ls].ch[0]].fa=ls,e[e[rs].ch[1]].fa=rs;
131         e[x].ch[0]=ls,e[x].ch[1]=rs,e[ls].fa=x,e[rs].fa=x;
132         e[x].l=e[x].r=id;
133         e[ls].l=l,e[ls].r=id-1;
134         e[rs].l=id+1,e[rs].r=r;
135         pushup(ls),pushup(rs),pushup(x);
136     }
137     splay(x,0);
138 }
139 void init(){
140     root=cnt=1;
141     e[1].l=1,e[1].r=n,e[1].sz=n;
142     f[n]=1;
143 }
144 int main(){
145     //freopen("testdata.in","r",stdin);
146     n=read(),m=read();
147     init();
148     while(m--){
149         int opt=read();
150         switch(opt){
151             case 1:{
152                 int oid=read()-ans,nid=read()-ans;
153                 int x=f.lower_bound(oid)->second;
154                 split(x,oid);
155                 ans=query(x);
156                 e[x].l=e[x].r=nid,f[nid]=x;
157                 print(ans),*o++='\n';
158                 break;
159             }
160             case 2:{
161                 int id=read()-ans;
162                 int x=f.lower_bound(id)->second;
163                 split(x,id);
164                 ans=query(x);
165                 pop(x);
166                 push_front(x);
167                 print(ans),*o++='\n';
168                 break;
169             }
170             case 3:{
171                 int id=read()-ans;
172                 int x=f.lower_bound(id)->second;
173                 split(x,id);
174                 ans=query(x);
175                 pop(x);
176                 push_back(x);
177                 print(ans),*o++='\n';
178                 break;
179             }
180             case 4:{
181                 int k=read()-ans;
182                 ans=getKth(k);
183                 print(ans),*o++='\n';
184                 break;
185             }
186         }
187     }
188     fwrite(obuf,o-obuf,1,stdout);
189     return 0;
190 }

 

posted @ 2018-07-30 16:23  bztMinamoto  阅读(315)  评论(0编辑  收藏  举报
Live2D