• loj2230 「BJOI2014」大融合


    LCT裸题

    我LCT学傻了这题明显可以树剖我不会树剖了

    本来的siz是Splay上的子树和,并没有什么用。

    所以每个点维护虚子树和子树和

    虚子树和即虚边连接的子树和,且只有在access和link操作更改。

    注意link操作

    原来的link:

    void link(int a,int b){makeroot(a);father[a]=b;}
    

    现在的link:

    //siz[i] i的子树和
    //_siz[i] i的虚子树和
    void link(int a,int b){makeroot(a);father[a]=b;_siz[b]+=siz[a];update(b);}
    

    然而上面是错的,因为a会成为b和b所有爸爸的虚子树和,你只更新了b。你错了。(滑稽)

    所以要先把b也放到根。

    void link(int a,int b){makeroot(a);makeroot(b);father[a]=b;_siz[b]+=siz[a];update(b);}
    
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cctype>
    using namespace std;
    #define rg register
    #define il inline
    #define sta static
    #define vd void
    il int gi(){
    	sta int x,flg;sta char ch;
    	x=flg=0,ch=getchar();
    	while(!isdigit(ch)){if(ch=='-')flg=-1;ch=getchar();}
    	while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    	return flg?-x:x;
    }
    const int maxn=100001;
    int ch[maxn][2],fa[maxn],siz[maxn],_siz[maxn];
    bool rev[maxn];
    typedef const int& fast;
    il bool isrt(fast x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
    il vd upd(fast x){if(x)siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1+_siz[x];}
    il vd Rev(fast x){if(x)rev[x]^=1,std::swap(ch[x][0],ch[x][1]);}
    il vd down(fast x){
    	if(!isrt(x))down(fa[x]);
    	if(rev[x])Rev(ch[x][0]),Rev(ch[x][1]),rev[x]=0;
    }
    il vd rotate(fast x){
    	sta int y,z,o;y=fa[x],z=fa[y],o=ch[y][1]==x;
    	if(!isrt(y))ch[z][ch[z][1]==y]=x;fa[x]=z;
    	ch[y][o]=ch[x][!o];fa[ch[x][!o]]=y;
    	fa[y]=x,ch[x][!o]=y;
    	upd(y);
    }
    il vd splay(fast x){
    	down(x);
    	sta int y,z;
    	for(y=fa[x],z=fa[y];!isrt(x);rotate(x),y=fa[x],z=fa[y])
    		if(!isrt(y))rotate(((ch[y][0]==x)^(ch[z][0]==y))?x:y);
    	upd(x);
    }
    il vd access(int x){for(rg int y=0;x;x=fa[y=x])splay(x),_siz[x]+=siz[ch[x][1]]-siz[y],ch[x][1]=y,upd(x);}
    il vd makert(fast x){access(x),splay(x),Rev(x);}
    il vd link(fast x,fast y){makert(x),makert(y),fa[x]=y,_siz[y]+=siz[x],upd(y);}
    il vd split(fast x,fast y){makert(x),access(y),splay(y);}
    int main(){
    #ifndef ONLINE_JUDGE
    	freopen("in.in","r",stdin);
    	freopen("out.out","w",stdout);
    #endif
    	int n=gi(),q=gi(),x,y;char opt[3];
    	for(rg int i=1;i<=n;++i)siz[i]=1;
    	while(q--){
    		scanf("%s",opt);x=gi(),y=gi();
    		if(opt[0]=='A')link(x,y);
    		else split(x,y),printf("%lld
    ",1ll*siz[x]*(siz[y]-siz[x]));
    	}
    	return 0;
    }
    
  • 相关阅读:
    Codeforces 每日一练 1213G+961E+1282B2
    AtCoder Beginner Contest 161题解
    Codeforces每日一练 495B+55C+1280C
    CF1062E 线段树/LCA
    Codeforces Round #697 (Div. 3) 题解
    Codeforces Round #511 (Div. 2) A~D题解
    Atcoder ABC 189 题解
    CF1093G 高维曼哈顿距离/线段树
    CF1117D Magic Gems 矩阵快速幂 DP
    CF1106E Lunar New Year and Red Envelopes DP
  • 原文地址:https://www.cnblogs.com/xzz_233/p/loj2230.html
Copyright © 2020-2023  润新知