您的位置:首页 > 其它

BZOJ1861 [Zjoi2006]Book 书架

2018-01-15 19:58 399 查看

Splay维护操作。

学习了一个很好的remove操作。

1 #include<bits/stdc++.h>
2 using namespace std;
3 const int N=8e4+5;
4 const int inf=1e9;
5 int fa
,c
[2],size
,pos
,a
,v
,n,m,rt;
6 void update(int x)
7 {
8     size[x]=size[c[x][0]]+size[c[x][1]]+1;
9 }
10 void rotate(int x,int &k)
11 {
12     int y=fa[x],z=fa[y];
13     int l=(c[y][1]==x);int r=l^1;
14     if(y==k)k=x;else c[z][c[z][1]==y]=x;
15     fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
16     c[y][l]=c[x][r];c[x][r]=y;
17     update(y);update(x);
18 }
19 void splay(int x,int &k)
20 {
21     while(x!=k)
22     {
23         int y=fa[x],z=fa[y];
24         if(y!=k)
25         {
26             if(x==c[y][0]^y==c[z][0])rotate(x,k);
27             else rotate(y,k);
28         }
29         rotate(x,k);
30     }
31 }
32 int find(int x,int k)
33 {
34     if(size[c[x][0]]+1==k)return x;
35     else if(size[c[x][0]]>=k)return find(c[x][0],k);
36     else return find(c[x][1],k-size[c[x][0]]-1);
37 }
38 void del(int k)
39 {
40     int x=find(rt,k-1);int y=find(rt,k+1);
41     splay(x,rt);splay(y,c[x][1]);
42     int z=c[y][0];c[y][0]=0;fa[z]=size[z]=0;
43     update(y);update(x);
44 }
45 void remove(int q,int w)
46 {
47     int k=pos[q],rank,x,y;
48
49     splay(k,rt);rank=size[c[rt][0]]+1;
50     del(rank);
51     if(w==inf)x=find(rt,n),y=find(rt,n+1);
52     else if(w==-inf)x=find(rt,1),y=find(rt,2);
53     else x=find(rt,rank+w-1),y=find(rt,rank+w);
54     splay(x,rt);splay(y,c[x][1]);
55     size[k]=1;fa[k]=y;c[y][0]=k;
56     update(y);update(x);
57 }
58 void build(int l,int r,int f)
59 {
60     if(l>r)return;
61     int mid=l+r>>1;
62     fa[mid]=f;c[f][mid>=f]=mid;v[mid]=a[mid];
63     if(l==r)
64     {
65         size[l]=1;return;
66     }
67     build(l,mid-1,mid);build(mid+1,r,mid);
68     update(mid);
69     return;
70 }
71 int main()
72 {
73     scanf("%d%d",&n,&m);
74     for(int i=2;i<=n+1;++i)
75     {
76         scanf("%d",&a[i]);pos[a[i]]=i;
77     }
78     build(1,n+2,0);rt=(n+3)>>1;char s[10];int k,ss,t;
79     for(int i=1;i<=m;++i)
80     {
81         scanf("%s",s);
82         if(s[0]=='Q')
83         {
84             scanf("%d",&k);
85             printf("%d\n",v[find(rt,k+1)]);
86         }
87         else if(s[0]=='T')
88         {
89             scanf("%d",&k);
90             remove(k,-inf);
91         }
92         else if(s[0]=='B')
93         {
94             scanf("%d",&k);
95             remove(k,inf);
96         }
97         else if(s[0]=='I')
98         {
99             scanf("%d%d",&ss,&t);remove(ss,t);
100         }
101         else
102         {
103             scanf("%d",&k);k=pos[k];
104             splay(k,rt);
105             printf("%d\n",size[c[rt][0]]-1);
106         }
107     }
108     return 0;
109 }
 

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: