zoukankan      html  css  js  c++  java
  • 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
    ");
    70             else printf("%d
    ",findkth(root->size-x)->key+add);
    71         }
    72     }
    73     printf("%d
    ",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
    ",ans);
    84     return 0;
    85 }
    View Code
    • 老爷题

        bzoj1500

  • 相关阅读:
    HDU 1874 畅通工程续
    HDU 1232 畅通工程
    HDU 1233 还是畅通工程
    HDU 1269 迷宫城堡
    洛谷 P1078 文化之旅
    POJ 3461 Oulipo
    最长链
    矩形面积求并
    有趣的数
    修复公路
  • 原文地址:https://www.cnblogs.com/Ngshily/p/5018997.html
Copyright © 2011-2022 走看看