• BZOJ4530 [BJOI2014] 大融合


    LCT维护子树信息(

    考虑维护两个值,一个虚子树信息,一个全部信息。

    因为虚子树只有在link和access的时候改变,可以方便的维护。

    具体可以康康代码。

    近期考虑写点大代码题练练手。

    //Love and Freedom.
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #define ll long long
    #define inf 20021225
    #define fa(x) t[x].fa
    #define ls(x) t[x].son[0]
    #define rs(x) t[x].son[1]
    #define nrt(x) (ls(fa(x))==x||rs(fa(x))==x)
    #define N 100010
    using namespace std;
    int read()
    {
        int s=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-') f=-1; ch=getchar();}
        while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
        return f*s;
    }
    struct node{int cnt,sum,fa,son[2]; bool tag;}t[N];
    void pushup(int x){t[x].sum=1+t[x].cnt+t[ls(x)].sum+t[rs(x)].sum;}
    void rotate(int x)
    {
        if(!nrt(x) || !x)    return;
        int f=fa(x),gf=fa(f);
        int k=rs(f)==x,p=k^1;
        if(nrt(f))    t[gf].son[rs(gf)==f]=x;
        if(t[x].son[p])    t[t[x].son[p]].fa=f;
        t[f].son[k]=t[x].son[p]; t[x].son[p]=f;
        t[x].fa=gf; t[f].fa=x;
        pushup(f); pushup(x);
    }
    void pushdown(int x)
    {
        if(t[x].tag)
        {
            swap(ls(x),rs(x));
            if(ls(x))    t[ls(x)].tag^=1;
            if(rs(x))    t[rs(x)].tag^=1;
            t[x].tag=0;
        }
    }
    void push(int x)
    {
        if(nrt(x))    push(fa(x));
        pushdown(x);
    }
    void splay(int x)
    {
        push(x);
        while(nrt(x))
        {
            int f=fa(x),gf=fa(f);
            if(nrt(gf))    (rs(f)==x)^(rs(gf)==f)?rotate(x):rotate(f);
            rotate(x);
        }
    }
    void access(int x)
    {
        int y=0;
        do
        {
            splay(x); t[x].cnt+=t[rs(x)].sum-t[y].sum;
            rs(x)=y; pushup(x); y=x; x=fa(x);
        }while(x);
    }
    void makeroot(int x)
    {
        access(x); splay(x); t[x].tag=1;
    }
    int getroot(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)
    {
        split(x,y);
        if(getroot(y)==x)    return;
        t[x].fa=y; t[y].cnt+=t[x].sum;
    }
    ll calc(int x,int y)
    {
        split(x,y);
        return 1ll*t[x].sum*(t[y].sum-t[x].sum);
    }
    char ch[10];
    int main()
    {
        int n=read(),m=read();
        for(int i=1;i<=n;i++)    t[i].sum=1;
        while(m--)
        {
            scanf("%s",ch); int x=read(),y=read();
            if(ch[0]=='A')    link(x,y);
            else    printf("%lld
    ",calc(x,y));
        }
        return 0;
    }
    View Code
  • 相关阅读:
    洛谷 P2023 BZOJ 1798 [AHOI2009]维护序列
    洛谷 P1640 BZOJ 1854 [SCOI2010]连续攻击游戏
    洛谷 P4300 BZOJ 1266 [AHOI2006]上学路线route
    洛谷 P1886 滑动窗口
    洛谷 P1063 能量项链
    洛谷 P1156 垃圾陷阱
    洛谷 P1854 花店橱窗布置
    洛谷 P3800 Power收集
    洛谷 P2285 BZOJ 1207 [HNOI2004]打鼹鼠
    day31
  • 原文地址:https://www.cnblogs.com/hanyuweining/p/11589666.html
Copyright © 2020-2023  润新知