bzoj 4530 [Bjoi2014]大融合——LCT维护子树信息

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4530

LCT维护子树 siz 。设 sm[ ] 表示轻儿子的 siz 和+1(1是自己的siz),siz[ ] 表示 splay 里 ( 两个儿子的 siz[ ] ) + sm[ cr ] 。在 access 里随便维护一下就好了。

一开始写的 siz[ ]  是 splay 里右儿子的 siz[ ] + sm[ cr ] ,但打 rev[ ]  的时候难以维护,所以弃了。

注意要先让一个点作为 splay 的根,再给它连右儿子,才能比较好地维护好;所以 link( ) 的时候注意 access( y ) !

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int N=1e5+5;
int n,Q,fa[N],c[N][2],siz[N],sm[N];
int sta[N],top;bool rev[N];
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;
}
bool isroot(int x){return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;}
void pshp(int x){siz[x]=sm[x]+siz[c[x][0]]+siz[c[x][1]];}
void Rev(int x)
{
  if(!rev[x])return;rev[x]=0;
  rev[c[x][0]]^=1;rev[c[x][1]]^=1;
  swap(c[x][0],c[x][1]);
}
void rotate(int x)
{
  int y=fa[x],z=fa[y],d=(x==c[y][1]);
  if(!isroot(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)
{
  sta[top=1]=x;
  for(int k=x;!isroot(k);k=fa[k])sta[++top]=fa[k];
  for(int i=top;i;i--)Rev(sta[i]);
  int y,z;
  while(!isroot(x))
    {
      y=fa[x];z=fa[y];
      if(!isroot(y))
    ((x==c[y][0])^(y==c[z][0]))?rotate(x):rotate(y);
      rotate(x);
    }
}
void access(int x)
{
  int t=0;
  while(x)
    {
      splay(x);
      sm[x]+=siz[c[x][1]];
      sm[x]-=siz[t];
      c[x][1]=t;
      pshp(x);/////
      t=x;x=fa[x];
    }
}
void makeroot(int x)
{
  access(x);splay(x);rev[x]^=1;
}
void link(int x,int y)
{
  makeroot(x);access(y);splay(y);//access()!!!
  fa[x]=y;sm[y]+=siz[x];siz[y]+=siz[x];
}
ll query(int x,int y)
{
  makeroot(x);access(y);splay(y);
  return (ll)siz[x]*sm[y];
}
int main()
{
  n=rdn();Q=rdn();
  for(int i=1;i<=n;i++)siz[i]=1,sm[i]=1;
  int x,y;char ch[3];
  while(Q--)
    {
      scanf("%s",ch);x=rdn();y=rdn();
      if(ch[0]=='A')link(x,y);
      else printf("%lld\n",query(x,y));
    }
  return 0;
}

 

posted on 2018-12-18 22:00  Narh  阅读(133)  评论(0编辑  收藏  举报

导航