splay初步

  • 模板题

    指针的狂欢,写的要飞起来了,yooo~

    bzoj3223文艺平衡树

      区间翻转

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define inf 0x3f3f3f3f
 4 #define maxn 100005
 5 struct node{
 6     node *fa,*s[2];
 7     int key,size,mark;
 8     node(){fa=s[0]=s[1]=NULL;key=mark=0;size=1;}
 9     node(int _key){fa=s[0]=s[1]=NULL;key=_key;size=1;}
10     bool getlr(){return fa->s[1]==this;}
11     node *link(int w,node *p){s[w]=p;if(p)p->fa=this;return this;}
12     void update(){size=1+(s[0]?s[0]->size:0)+(s[1]?s[1]->size:0);}
13     void push_down(){
14         if(mark){
15             if(s[0])s[0]->mark^=1;
16             if(s[1])s[1]->mark^=1;
17             swap(s[0],s[1]);
18             mark^=1;
19         }
20     }
21 }*root,data[maxn],*laji=data;
22 void rot(node *p){
23     node *q=p->fa->fa;
24     p->getlr()?p->link(0,p->fa->link(1,p->s[0])):p->link(1,p->fa->link(0,p->s[1]));
25     p->fa->update();
26     if(q)q->link(q->s[1]==p->fa,p);
27     else p->fa=NULL,root=p;
28 }
29 void splay(node *p,node *tar){
30     while(p->fa!=tar&&p->fa->fa!=tar)
31         p->getlr()==p->fa->getlr()?(rot(p->fa),rot(p)):(rot(p),rot(p));
32     if(p->fa!=tar)rot(p);
33     p->update();
34 }
35 void insert(int k){
36     node *p=root,*q=NULL;
37     while(p){p->push_down();q=p;p=p->s[p->key<k];}
38     p=new(laji++)node(k);
39     if(!q){root=p;return;}
40     q->link(q->key<k,p);q->update();splay(p,0);
41 }
42 node *findkth(int k){
43     node *p=root;
44     p->push_down();
45     int w=p->s[0]?p->s[0]->size:0;
46     while(w+1!=k){
47         if(k<=w)p=p->s[0];
48         else k-=w+1,p=p->s[1];
49         p->push_down();
50         w=p->s[0]?p->s[0]->size:0;
51     }
52     splay(p,0);return p;
53 }
54 void flip(int l,int r){
55     node *p=findkth(l);
56     node *q=findkth(r+2);
57     splay(p,q);
58     p->s[1]->mark^=1;
59 }
60 void print(node *p){
61     p->push_down();
62     if(p->s[0])print(p->s[0]);
63     if(p->key!=inf&&p->key!=-inf)printf("%d ",p->key);
64     if(p->s[1])print(p->s[1]);
65 }
66 int main(){
67     int n,m,a,b;
68     scanf("%d%d",&n,&m);
69     insert(-inf);insert(inf);
70     for(int i=1;i<=n;i++)
71         insert(i);
72     for(int i=1;i<=m;i++){
73         scanf("%d%d",&a,&b);
74         flip(a,b);
75     }
76     print(root);
77     return 0;
78 }
View Code

    bzoj1503郁闷的出纳员

      终于完成了treap的遗愿

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define maxn 100005
 4 #define inf 0x3f3f3f3f
 5 struct node{
 6     node *fa,*s[2];
 7     int key,size;
 8     node(){fa=s[0]=s[1]=0;size=1;key=0;}
 9     node(int _key){fa=s[0]=s[1]=0;size=1;key=_key;}
10     bool getlr(){return fa->s[1]==this;}
11     node *link(int w,node *p){s[w]=p;if(p)p->fa=this;return this;}
12     void update(){size=1+(s[0]?s[0]->size:0)+(s[1]?s[1]->size:0);}
13 }*root,data[maxn],*laji=data;
14  
15 void rot(node *p){
16     node *q=p->fa->fa;
17     p->getlr()?p->link(0,p->fa->link(1,p->s[0])):p->link(1,p->fa->link(0,p->s[1]));
18     p->fa->update();
19     if(q)q->link(q->s[1]==p->fa,p);
20     else {p->fa=0;root=p;}
21 }
22 void splay(node *p,node *tar){
23     while(p->fa!=tar&&p->fa->fa!=tar)
24         p->getlr()==p->fa->getlr()?(rot(p->fa),rot(p)):(rot(p),rot(p));
25     if(p->fa)rot(p);
26     p->update();
27 }
28 void insert(int k){
29     node *p=root,*q=NULL;
30     while(p){q=p;p=p->s[p->key<k];}
31     p=new(laji++) node(k);
32     if(!q){root=p;return;}
33     q->link(q->key<k,p);
34     q->update();
35     splay(p,0);
36      
37 }
38 node *findkth(int k){
39     node *p=root;
40     int w=p->s[0]?p->s[0]->size:0;
41     while(w+1!=k){
42         if(w>=k)p=p->s[0];
43         else{p=p->s[1];k-=w+1;}
44         w=p->s[0]?p->s[0]->size:0;
45     }
46     splay(p,0);return p;
47 }
48 int main(){
49     int n,lim,x;
50     char op[5];
51     insert(-inf);insert(inf);
52     scanf("%d%d",&n,&lim);
53     int add=0,num=0;
54     for(int i=1;i<=n;i++){
55         scanf("%s%d",op,&x);
56         if(op[0]=='I'){
57             if(x>=lim)insert(x-add);
58         }
59         else if(op[0]=='A')add+=x;
60         else if(op[0]=='S'){
61             add-=x;
62             insert(lim-add);
63             num+=root->s[0]?root->s[0]->size-1:0;
64             root=root->s[1];
65             root->fa=NULL;
66             insert(-inf);
67         }
68         else{
69             if(root->size-2<x)printf("-1\n");
70             else printf("%d\n",findkth(root->size-x)->key+add);
71         }
72     }
73     printf("%d\n",num);
74     return 0;
75 }
76 
View Code

    bzoj1208宠物收养所

      发现并没有写过删除操作,,,splay的删除和treap的正相反,treap把要删除的节点转到叶子节点,而splay把要删除的节点转到根,然后把它的前驱或后继当根

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 
 4 #define mod 1000000
 5 #define maxn 80005
 6 int root,size,t1,t2;
 7 int fa[maxn],c[maxn][2],key[maxn];
 8 void rot(int x,int &k){
 9     int y=fa[x],z=fa[y];
10     int p=(c[y][1]==x);
11     int q=p^1;
12     if(y==k)k=x;
13     else{
14         if(c[z][0]==y)c[z][0]=x;
15         else c[z][1]=x;
16     }
17     fa[x]=z;fa[y]=x;fa[c[x][q]]=y;
18     c[y][p]=c[x][q];c[x][q]=y;
19 }
20 void splay(int x,int &k){
21     while(x!=k){
22         int y=fa[x],z=fa[y];
23         if(y!=k){
24             if((c[y][0]==x)^(c[z][0]==y))rot(x,k);
25             else rot(y,k);
26         }
27         rot(x,k);
28     }
29 }
30 void insert(int &k,int x,int pre){
31     if(!k){
32         k=++size;
33         key[k]=x;fa[k]=pre;
34         splay(k,root);
35         return;
36     }
37     if(x<key[k])insert(c[k][0],x,k);
38     else insert(c[k][1],x,k);
39 }
40 void del(int x){
41     splay(x,root);
42     if(c[x][0]*c[x][1]==0)
43         root=c[x][0]+c[x][1],fa[root]=0;
44     else{
45         int k=c[x][1];
46         while(c[k][0])k=c[k][0];
47         splay(k,root);
48         c[k][0]=c[x][0];fa[c[x][0]]=k;
49     }
50 }
51 void pro(int k,int x){
52     if(!k)return;
53     if(x>=key[k])t1=k,pro(c[k][1],x);
54     else pro(c[k][0],x);
55 }
56 void sub(int k,int x){
57     if(!k)return;
58     if(x<=key[k])t2=k,sub(c[k][0],x);
59     else sub(c[k][1],x);
60 }
61 int main(){
62     freopen("1.in","r",stdin);
63     int n,kind,op,x;
64     scanf("%d",&n);
65     int ans=0;
66     for(int i=1;i<=n;i++){
67         scanf("%d%d",&op,&x);
68         if(!root)kind=op,insert(root,x,0);
69         else if(op==kind)insert(root,x,0);
70         else{
71             t1=t2=-1;
72             pro(root,x);
73             sub(root,x);
74             if(t1==-1)ans=(ans+key[t2]-x)%mod,del(t2);
75             else if(t2==-1)ans=(ans+x-key[t1])%mod,del(t1);
76             else{
77                 if(x-key[t1]<=key[t2]-x)
78                     ans=(ans+x-key[t1])%mod,del(t1);
79                 else ans=(ans+key[t2]-x)%mod,del(t2);
80             }
81         }
82     }
83     printf("%d\n",ans);
84     return 0;
85 }
View Code
  • 老爷题

    bzoj1500

posted @ 2015-12-04 12:53  Ngshily  阅读(171)  评论(0编辑  收藏  举报