• 【bzoj4530】[Bjoi2014]大融合 LCT维护子树信息


    题解:

    lct维护子树信息

    推荐https://www.cnblogs.com/GXZlegend/p/7061458.html,非常详细

    总的来说就是 维护虚树信息和子树信息

    虚树信息只有在access和link时才会改变

    下面是对拍程序

    my

    #include <bits/stdc++.h>
    using namespace std;
    char cc;
    int x,y,n,m;
    #define N 200000
    int count2[N],count3[N],ls[N],rs[N],fa[N];
    bool rev[N];
    void updata(int x)
    {
      count2[x]=count3[x]+count2[ls[x]]+count2[rs[x]]+1;
    }
    void down(int x)
    {
      if (!rev[x]) return;
      swap(ls[x],rs[x]);
      rev[ls[x]]^=1; rev[rs[x]]^=1;
      rev[x]=0;
    }
    bool pd(int x)
    {
      int y=fa[x];
      if (ls[y]!=x&&rs[y]!=x) return(0);
      else return(1);
    }
    void rotate(int x,int y)
    {
      int ft=fa[x];
      if (y==1)
      {
        rs[ft]=ls[x];
        if (ls[x]) fa[ls[x]]=ft;
      } else
      {
        ls[ft]=rs[x];
        if (rs[x]) fa[rs[x]]=ft;
      }
      fa[x]=fa[ft];
      if (pd(ft))
      {
        if (ls[fa[ft]]==ft) ls[fa[ft]]=x;
        else rs[fa[ft]]=x;
      }
      fa[ft]=x;
      if (y==1) ls[x]=ft; else rs[x]=ft;
      updata(ft); updata(x);
    }
    void dfs(int x)
    {
      if (pd(x)) dfs(fa[x]);
      down(x);
    }
    void splay(int x)
    {
      dfs(x);
      int ft=fa[x];
      while (pd(x))
      {
        if (!pd(ft))
        {
          if (x==ls[ft]) rotate(x,2);
          else rotate(x,1);
        } else
        {
          if (ft==ls[fa[ft]])
          {
            if (x==ls[ft])
              rotate(ft,2),rotate(x,2);
            else rotate(x,1),rotate(x,2); 
          } else
          {
            if (x==rs[ft])
              rotate(ft,1),rotate(x,1);
            else rotate(x,2),rotate(x,1);
          }
        }
        ft=fa[x];
      }
    }
    void access(int x)
    {
      for (int y=0;x;y=x,x=fa[x])
        splay(x),count3[x]+=count2[rs[x]]-count2[y]
        ,rs[x]=y,updata(x);
    }
    void makeroot(int x)
    {
       access(x);
       splay(x);
       rev[x]^=1;
    }
    int findroot(int x)
    {
       access(x);
       splay(x);
       while (ls[x]) x=ls[x];
       return x;
    }
    void split(int x,int y)
    {
      makeroot(x);
      access(y);
      splay(y);
    }
    void link(int x,int y)
    {
      makeroot(x);
      if (findroot(y)!=x)
      { 
        fa[x]=y;
        count3[y]+=count2[x];
        updata(y);
      }
    }
    int main()
    {
      freopen("noip.in","r",stdin);
      freopen("noip.out","w",stdout);
      std::ios::sync_with_stdio(false);
      cin>>n>>m;
      for (int i=1;i<=m;i++)
      {
        cin>>cc>>x>>y;
        if (cc=='A')
        {
          link(x,y);
        } else
        {
          split(x,y);
          int tmp=count2[x];
          split(y,x);
          tmp*=count2[y];
          cout<<tmp<<endl;
        }
      }
      return 0;
    }

    maker

    #include <bits/stdc++.h>
    using namespace std;
    int fa[100000];
    bool f[1010][1010];
    int find(int x)
    {
      if (fa[x]!=x) return(find(fa[x]));
      else return(x);
    }
    int main()
    {
      freopen("noip.in","w",stdout);
      int n=1000,m=800;
      srand(time(0));
      cout<<n<<" "<<m<<endl;
      for (int i=1;i<=n;i++) fa[i]=i;
      for (int i=1;i<=600;i++)
      {
        while (1)
        {
          int x=rand()%n+1,y=rand()%n+1;
          if (find(x)!=find(y))
          {
            f[x][y]=1; f[y][x]=1;
            fa[find(x)]=find(y);
            cout<<"A "<<x<<" "<<y<<endl;
            break;
          }
        }
      }
      for (int i=1;i<=200;i++)
      {
        while (1)
        {
          int x=rand()%n+1,y=rand()%n+1;
          if (f[x][y])
          {
            cout<<"Q "<<x<<" "<<y<<endl;
            break;
          }
        }
      }
      return 0;
    } 

    dp

    #include <cstdio>
    #include <algorithm>
    #define N 100010
    using namespace std;
    int fa[N] , c[2][N] , si[N] , sum[N] , rev[N];
    char str[5];
    void pushup(int x)
    {
        sum[x] = sum[c[0][x]] + sum[c[1][x]] + si[x] + 1;
    }
    void pushdown(int x)
    {
        if(rev[x])
        {
            int l = c[0][x] , r = c[1][x];
            swap(c[0][l] , c[1][l]) , swap(c[0][r] , c[1][r]);
            rev[l] ^= 1 , rev[r] ^= 1 , rev[x] = 0;
        }
    }
    bool isroot(int x)
    {
        return c[0][fa[x]] != x && c[1][fa[x]] != x;
    }
    void update(int x)
    {
        if(!isroot(x)) update(fa[x]);
        pushdown(x);
    }
    void rotate(int x)
    {
        int y = fa[x] , z = fa[y] , l = (c[1][y] == x) , r = l ^ 1;
        if(!isroot(y)) c[c[1][z] == y][z] = x;
        fa[x] = z , fa[y] = x , fa[c[r][x]] = y , c[l][y] = c[r][x] , c[r][x] = y;
        pushup(y) , pushup(x);
    }
    void splay(int x)
    {
        update(x);
        while(!isroot(x))
        {
            int y = fa[x] , z = fa[y];
            if(!isroot(y))
            {
                if((c[0][y] == x) ^ (c[0][z] == y)) rotate(x);
                else rotate(y);
            }
            rotate(x);
        }
    }
    void access(int x)
    {
        int t = 0;
        while(x) splay(x) , si[x] += sum[c[0][x]] - sum[t] , c[0][x] = t , pushup(x) , t = x , x = fa[x];
    }
    void makeroot(int x)
    {
        access(x) , splay(x) , swap(c[0][x] , c[1][x]) , rev[x] = 1;
    }
    void split(int x , int y)
    {
        makeroot(x) , makeroot(y);
    }
    void link(int x , int y)
    {
        split(x , y) , fa[x] = y , si[y] += sum[x] , pushup(y);
    }
    int main()
    {
      freopen("noip.in","r",stdin);
      freopen("noip2.out","w",stdout);
        int n , m , i , x , y;
        scanf("%d%d" , &n , &m);
        for(i = 1 ; i <= n ; i ++ ) sum[i] = 1;
        while(m -- )
        {
            scanf("%s%d%d" , str , &x , &y);
            if(str[0] == 'A') link(x , y);
            else split(x , y) , printf("%lld
    " , (long long)sum[x] * (sum[y] - sum[x]));
        }
        return 0;
    }
  • 相关阅读:
    iOS-禁止scrollview垂直方向滚动,只允许水平方向滚动;或只允许垂直方向滚动
    MongoDB安装
    Vue运用
    egg-middleware 中间件
    如何判断扫码的客户端是微信还是支付宝
    node 短信接口的调用
    Mui 长按保存图片
    egg-sequelize --- nodejs
    egg-mongoose --- nodejs
    Mongoose 基本用法
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/8748065.html
Copyright © 2020-2023  润新知