zoukankan      html  css  js  c++  java
  • HDU6394(LCT)

    类似于弹飞绵羊的做法 我们对于当前节点往上能达到的节点连边 查询的话直接查询这个点到根的距离即可(只涉及cut和Link的LCT)

    #include <algorithm>
    #include <iostream>
    #include <vector>
    const int MAXN=1e5+10; 
    #define ll long long
    using namespace std;
    vector<int>vec[MAXN];
    struct FastIO
    {
        static const int S=200;
        int wpos;
        char wbuf[S];
        FastIO():wpos(0){}
        inline int xchar()
        {
            static char buf[S];
            static int len=0,pos=0;
            if(pos==len) pos=0,len=fread(buf,1,S,stdin);
            if(pos==len) exit(0);
            return buf[pos++];
        }
        inline int read()
        {
            int s=1,c=xchar(),x=0;
            while(c<=32) c=xchar();
            if(c=='-') s=-1,c=xchar();
            for(;'0'<=c&&c<='9';c=xchar()) x=x*10+c-'0';
            return x*s;
        }
        ~FastIO()
        {
            if(wpos) fwrite(wbuf,1,wpos,stdout),wpos=0;
        }
    }io;
    bool rt[MAXN];int ch[MAXN][2],size[MAXN],pre[MAXN],fa[MAXN][21],n,a[MAXN];
    int dep[MAXN];
    void dfs(int v,int f,int deep){
      fa[v][0]=f;dep[v]=deep+1;
      for(int i=0;i<vec[v].size();i++){
          if(vec[v][i]!=f){
              dfs(vec[v][i],v,deep+1);
          }
      }
    }
    void dfs1(int v){
        for(int i=1;i<=20;i++)fa[v][i]=fa[fa[v][i-1]][i-1];
        for(int i=0;i<vec[v].size();i++)if(vec[v][i]!=fa[v][0])dfs1(vec[v][i]);
    }
    int Lca(int v,int k){
        for(int i=0;i<=20;i++)if((k&(1<<i)))v=fa[v][i];
        return v;
    }
    void P(int r){
        if(!rt[r]) P(pre[r]);//传标记 
    }
    void up(int x){
        size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
    }
    void rotate(int x,int kind){
        int y=pre[x];
        ch[y][!kind]=ch[x][kind];
        pre[ch[x][kind]]=y;
        if(rt[y]) rt[y]=false,rt[x]=true;
        else ch[pre[y]][ch[pre[y]][1]==y]=x;
        pre[x]=pre[y];ch[x][kind]=y;pre[y]=x;
        up(y);
    }
    void splay(int x){
        //P(x);
        while(!rt[x]){
            if(rt[pre[x]]) rotate(x,ch[pre[x]][0]==x);
            else{
                int y=pre[x];
                int kind=(ch[pre[y]][0]==y);
                if(ch[y][kind]==x){
                    rotate(x,!kind);rotate(x,kind);
                }
                else{
                    rotate(y,kind);rotate(x,kind);
                }
            }
        }
        up(x);
    }
    int access(int u){
        int y=0;int x=u;
        while(u){
            splay(u);
            if(ch[u][1]) rt[ch[u][1]]=1,pre[ch[u][1]]=u,ch[u][1]=0;
            ch[u][1]=y;pre[y]=u;
            up(u); 
            if(y) rt[y]=false;
            up(u);
            y=u;u=pre[u];
        }
        splay(x);
        return size[ch[x][0]]+1;
    }
    void Cut(int u,int v){
        splay(u);
        if(ch[u][0]) pre[ch[u][0]]=pre[u],rt[ch[u][0]]=1,ch[u][0]=0;
        up(u);
        pre[u]=v; 
    }
    int main(){
        int _=io.read();
        while(_--){
        n=io.read();
        int u,v;
        for(int i=1;i<n;i++)u=io.read(),vec[u].push_back(i+1);
        dfs(1,0,0);dfs1(1);
        for(int i=1;i<=n;i++){
            a[i]=io.read();
            rt[i]=1;ch[i][0]=ch[i][1]=0;size[i]=1;
        }
        for(int i=1;i<=n;i++){
            if(dep[i]-a[i]>=0) pre[i]=Lca(i,a[i]);
            else pre[i]=0;
        }
        int m;m=io.read();
        int op,t1,t2;
        for(int i=1;i<=m;i++){
            op=io.read();
            if(op==1) t1=io.read(),printf("%d
    ",access(t1));
            else{
                t1=io.read();t2=io.read();
                if(dep[t1]-t2>=0) Cut(t1,Lca(t1,t2));
                else Cut(t1,0);
            }
        }
        for(int i=1;i<=n;i++)vec[i].clear();
    }
        return 0;
    }
    
  • 相关阅读:
    过滤器和拦截器的区别
    sql注入
    JavaScript学习
    Linux简单学习
    HTML DOM学习
    Java集合
    java 多线程学习
    常用的OO设计原则
    JAVA设计模式一策略模式(Strategy Pattern)
    201521123071《Java程序设计》第1周学习总结
  • 原文地址:https://www.cnblogs.com/wang9897/p/9471916.html
Copyright © 2011-2022 走看看