zoukankan      html  css  js  c++  java
  • CF 1172E Nauuo and ODT ——LCT

    题目:http://codeforces.com/contest/1172/problem/E

    LCT好题。

    考虑对每个颜色求出 “不是该颜色的点组成的连通块的 siz2 之和” 。每个颜色用 LCT 维护不是该颜色的点。

    LCT 维护的一个连通块,其最顶端的点是该颜色,其他部分满足 “不是该颜色” ;再维护子树的 siz2 ,就能做了。

    注意代码里的 p[ ] 要开 2*n 那么大!!!

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    int rdn()
    {
      int ret=0;bool fx=1;char ch=getchar();
      while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();}
      while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();
      return fx?ret:-ret;
    }
    ll Sqr(int x){return (ll)x*x;}
    const int N=4e5+5,M=N<<1;
    int n,m,col[N],hd[N],xnt,to[M],nxt[M];
    int f[N],fa[N],c[N][2],siz[N],sizi[N];
    int p[M],tot; bool vis[N];ll siz2i[N],tmp,dlt[N];//p[M]!!
    bool isrt(int x){return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;}
    void pshp(int x){siz[x]=siz[c[x][0]]+siz[c[x][1]]+sizi[x]+1;}
    void rotate(int x)
    {
      int y=fa[x],z=fa[y]; bool d=(x==c[y][1]);
      if(!isrt(y))c[z][y==c[z][1]]=x;
      fa[x]=z; fa[y]=x; fa[c[x][!d]]=y;
      c[y][d]=c[x][!d]; c[x][!d]=y;
      pshp(y); pshp(x);
    }
    void splay(int x)
    {
      for(int y,z;!isrt(x);rotate(x))
        {
          y=fa[x]; z=fa[y];
          if(!isrt(y))
        ((y==c[z][0])^(x==c[y][0]))?rotate(x):rotate(y);
        }
    }
    void access(int x)
    {
      for(int t=0;x;t=x,x=fa[x])
        {
          splay(x); int y=c[x][1];
          sizi[x]+=siz[y]; siz2i[x]+=Sqr(siz[y]);
          sizi[x]-=siz[t]; siz2i[x]-=Sqr(siz[t]);
          c[x][1]=t; pshp(x);
        }
    }
    int fnd_rt(int x)
    {
      access(x); splay(x);
      while(c[x][0])x=c[x][0];
      splay(x); return x;
    }
    void link(int x)
    {
      splay(x);//x is top so always accessed
      tmp-=Sqr(siz[c[x][1]])+siz2i[x];
      int y=f[x],rt=fnd_rt(y);//rt splayed
      splay(rt);///y accessed
      tmp-=Sqr(siz[c[rt][1]]);////+siz2i[rt];
      splay(y); fa[x]=y;
      sizi[y]+=siz[x]; siz2i[y]+=Sqr(siz[x]); pshp(y);
      access(x); splay(rt);//access(x)!!!
      tmp+=Sqr(siz[c[rt][1]]);
    }
    void cut(int x)
    {
      int rt=fnd_rt(x);//x accessed//rt splayed
      tmp+=siz2i[x];//!!!
      tmp-=Sqr(siz[c[rt][1]]);
      int y=f[x]; splay(y); c[y][1]=0; fa[x]=0; pshp(y);
      //x accessed and is bottom so is c[y][1]
      splay(rt);
      tmp+=Sqr(siz[c[rt][1]]);
    }
    namespace Q{
      int hd[N],xnt,to[M],id[M],nxt[M];
      void add(int x,int y,int i)
      {
        to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt;id[xnt]=i;
      }
      void solve(int cr)
      {
        tot=0;
        for(int i=hd[cr];i;i=nxt[i])
          p[++tot]=i;
        for(int i=tot,d;i;i--)
          {
        tmp=0; d=p[i];
        if(vis[to[d]]) link(to[d]);
        else cut(to[d]);
        dlt[id[d]]+=tmp;
        vis[to[d]]^=1;
          }
      }
      void solve2(int cr)
      {
        for(int i=hd[cr];i;i=nxt[i])
          {
        tmp=0;
        if(vis[to[i]]) link(to[i]);
        else cut(to[i]);
        vis[to[i]]^=1;
          }
      }
    }
    namespace I{
      int hd[N],xnt,to[N],nxt[N];
      void add(int x,int y)
      {to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt;}
      void solve(int cr)
      {
        tot=0;
        for(int i=hd[cr];i;i=nxt[i])
          p[++tot]=to[i];
        tmp=0;
        for(int i=tot;i;i--)
          {
        if(vis[p[i]]) link(p[i]);
        else cut(p[i]);
        vis[p[i]]^=1;
          }
        dlt[0]+=tmp;
      }
      void solve2(int cr)
      {
        for(int i=hd[cr];i;i=nxt[i])
          {
        tmp=0;
        if(vis[to[i]]) link(to[i]);
        else cut(to[i]);
        vis[to[i]]^=1;///
          }
      }
    }
    void add(int x,int y){to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt;}
    void ini_dfs(int cr,int fa)
    {
      f[cr]=fa;
      for(int i=hd[cr],v;i;i=nxt[i])
        if((v=to[i])!=fa) ini_dfs(v,cr);
    }
    int main()
    {
      n=rdn();m=rdn();
      for(int i=2;i<=n+1;i++)
        { col[i]=rdn(); I::add(col[i],i);}
      for(int i=1,u,v;i<n;i++)
        u=rdn()+1,v=rdn()+1,add(u,v),add(v,u);
      add(1,2); add(2,1); ini_dfs(1,0);
      for(int i=1,u,d;i<=m;i++)
        {
          u=rdn()+1; d=rdn(); Q::add(col[u],u,i);
          col[u]=d; Q::add(d,u,i);
        }
      for(int i=2;i<=n+1;i++)siz[i]=1;//
      for(int i=2;i<=n+1;i++) link(i);
      dlt[0]=(ll)n*n*n;
      for(int i=1;i<=n;i++)
        {
          I::solve(i); Q::solve(i);
          Q::solve2(i); I::solve2(i);
        }
      ll ans=(ll)n*n*n;
      for(int i=0;i<=m;i++)
        {
          ans-=dlt[i]; printf("%lld
    ",ans);
        }
      return 0;
    }
    View Code
  • 相关阅读:
    无缘无故出现IDEA无法引入包和类的问题?
    JDK8新特性——Optional
    【工具类】ExcelUtils
    【Mybatis-Plus学习笔记(二)】查询
    【Mybatis-Plus学习笔记(一)】入门
    【Mybatis学习笔记】目录
    【超详细全过程】DataGrip的安装与使用
    【超详细全过程】python环境配置+编辑器安装(python+pycharm)
    【Mybatis工具(五)】雪花算法
    【Mybatis工具(四)】UUID实现原理及其Java实现
  • 原文地址:https://www.cnblogs.com/Narh/p/11000111.html
Copyright © 2011-2022 走看看