zoukankan      html  css  js  c++  java
  • [HNOI2017]单旋

    题解:

    我们可以单独的用LCT来维护每个点的深度(先把当前根转到根,再查询到根的路径长度就可以了),这棵splay由于只需要旋转最大最小值,手玩发现树的形态基本没变,所以我们就可以手动维护这个splay的形态,记录好根,父亲,儿子的状态然后用LCT求深度即可.

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstdlib>
      4 #include<algorithm>
      5 #include<cmath>
      6 #include<cstring>
      7 #include<queue>
      8 #include<vector>
      9 #include<set>
     10 #define RG register
     11 #define LL long long int
     12 #define MAXN 500010
     13 using namespace std;
     14 const int INF=1e9;
     15 struct node{
     16   int id;int x;
     17 }op[MAXN];
     18 int m;
     19 int root;
     20 int ch[MAXN][2],fa[MAXN],siz[MAXN],rev[MAXN];
     21 int st[MAXN],top;
     22 int pp[MAXN];
     23 int c[MAXN][2],f[MAXN];
     24 set<int> s;
     25 set<int>::iterator it;
     26 void clear(int x){ch[x][0]=ch[x][1]=fa[x]=0;}
     27 void up(int x){siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;}
     28 bool isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
     29 void down(int x)
     30 {
     31   if(rev[x]){
     32     swap(ch[x][0],ch[x][1]); 
     33     rev[ch[x][0]]^=1;rev[ch[x][1]]^=1;rev[x]^=1;
     34   }
     35 }
     36 void rotate(int x)
     37 {
     38   int old=fa[x],oldf=fa[old],rel=(ch[old][1]==x);
     39   if(!isroot(old)) ch[oldf][ch[oldf][1]==old]=x;
     40   fa[x]=oldf;fa[ch[x][rel^1]]=old;ch[old][rel]=ch[x][rel^1];
     41   fa[old]=x;ch[x][rel^1]=old;
     42   up(old);up(x);return;
     43 }
     44 void splay(int x)
     45 {
     46   int old,oldf,now=x;top=0;st[++top]=now;
     47   while(!isroot(now)) st[++top]=fa[now],now=fa[now];
     48   while(top>0){down(st[top]);top--;}
     49   while(!isroot(x))
     50     {
     51       old=fa[x];oldf=fa[old];
     52       if(!isroot(old))
     53     {
     54       if((ch[old][0]==x)^(ch[oldf][0]==old)) rotate(x);
     55       else rotate(old);
     56     }
     57       rotate(x);
     58     }
     59 }
     60 void access(int x){int t(0);while(x) splay(x),ch[x][1]=t,t=x,up(x),x=fa[x];}
     61 void makeroot(int x){access(x);splay(x);rev[x]^=1;}
     62 void link(int x,int y){ if(!x||!y) return; makeroot(x);fa[x]=y,up(y);}
     63 void cut(int x,int y){
     64   if(!x||!y) return;
     65   makeroot(x);access(y);splay(y);
     66  ch[y][0]=fa[x]=0,up(x),up(y);
     67 }
     68 int query(int x){makeroot(root);access(x);splay(x);return siz[x];}
     69 int main()
     70 {
     71   freopen("1.in","r",stdin);
     72   scanf("%d",&m);
     73   for(int i=1;i<=m;i++){
     74     scanf("%d",&op[i].id);
     75     if(op[i].id==1) scanf("%d",&op[i].x),pp[++pp[0]]=op[i].x;
     76   }
     77   sort(pp+1,pp+pp[0]+1);int cnt=unique(pp+1,pp+pp[0]+1)-pp-1;   
     78   s.insert(INF);s.insert(-INF);int tot=0;
     79   for(int i=1;i<=m;i++)
     80     {
     81       if(op[i].id==1){
     82     tot++;op[i].x=lower_bound(pp+1,pp+cnt+1,op[i].x)-pp;
     83     if(tot==1) {root=op[i].x;printf("1
    ");}
     84     else{
     85       it=s.upper_bound(op[i].x);int nex=*it;it--;int pre=*it;
     86       int dep=0,x;
     87       if(pre!=-INF){int now=query(pre);if(now>dep){dep=now,x=pre;}}
     88       if(nex!=INF){int now=query(nex);if(now>dep){dep=now,x=nex;}}
     89       printf("%d
    ",dep+1);
     90       c[x][op[i].x>x]=op[i].x;f[op[i].x]=x;link(x,op[i].x);
     91     }
     92     s.insert(op[i].x);
     93       }
     94       if(op[i].id==2){
     95     if(tot==1) printf("1
    ");
     96     else{
     97       it=s.begin();it++;int x=*it;int y=c[x][1],z=f[x],dep=query(x);
     98       if(root!=x){
     99         cut(x,z);cut(x,y);link(z,y);link(x,root);
    100         c[x][1]=root;f[root]=x;f[x]=0;root=x;
    101         f[y]=z;c[z][0]=y;
    102       } 
    103       printf("%d
    ",dep);
    104     }
    105       }
    106       if(op[i].id==3){
    107     if(tot==1){printf("1
    ");continue;}
    108     else{
    109       it=s.end();it--;it--;int x=*it;int y=c[x][0],z=f[x],dep=query(x);
    110       if(root!=x){
    111         cut(x,z);cut(x,y);link(z,y);link(root,x);
    112         c[x][0]=root;f[root]=x;f[x]=0;root=x;
    113         f[y]=z;c[z][1]=y;
    114       }
    115       printf("%d
    ",dep);
    116     }
    117       }
    118       if(op[i].id==4){
    119     if(tot==1){s.erase(s.find(root));clear(root);root=0;tot--;printf("1
    ");}
    120     else{
    121       it=s.begin();it++;int x=*it;int y=c[x][1],z=f[x],dep=query(x);tot--;
    122       if(x==root) root=y;
    123       cut(x,y);cut(x,z);link(y,z);clear(x);
    124       f[y]=z;c[z][0]=y;
    125       printf("%d
    ",dep);s.erase(s.find(x));
    126     }
    127       }
    128       if(op[i].id==5){
    129     if(tot==1){s.erase(s.find(root));clear(root);root=0;tot--;printf("1
    ");}
    130     else{
    131       it=s.end();it--;it--;int x=*it;int y=c[x][0],z=f[x],dep=query(x);tot--;
    132       if(x==root) root=y;
    133       cut(x,y);cut(x,z);link(y,z);clear(x);
    134       f[y]=z;c[z][1]=y;
    135       printf("%d
    ",dep);s.erase(s.find(x));
    136     }
    137       }
    138     }
    139   return 0;
    140 }
  • 相关阅读:
    预览图片功能 直接复制就OK
    记录:express返回自定义http状态吗
    Git tag 给当前分支打标签
    css双飞翼和圣杯布局
    简单模拟MVVM数据双向绑定
    JS的自定义事件(观察者模式)
    js模拟触发事件
    QueryString和BASE64
    WebResource.axd文件的配置和使用
    处理json中的异常字符
  • 原文地址:https://www.cnblogs.com/Landlord-greatly/p/8081752.html
Copyright © 2011-2022 走看看