zoukankan      html  css  js  c++  java
  • [BJOI2014]大融合

    题面理解很容易,求树上两颗树节点数之和。

    这里需要lct维护虚子树信息。

    对于每个节点,我们记录认的儿子和不认的儿子大小之和(s),和不认的儿子大小和(sx)。

    在access中,x节点换儿子时,需要对x的sx值加上前任儿子值,在减去现任儿子值。

    代码:

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    #define N 100500
    #define ll long long
    ll n,m;
    ll ch[N][2],fa[N],s[N],sx[N];
    bool rt[N],res[N];
    void update(ll x)
    {
        s[x] = sx[x]+s[ch[x][0]]+s[ch[x][1]]+1;
    }
    void reser(ll x)
    {
        res[x]^=1;
        swap(ch[x][0],ch[x][1]);
    }
    void pushdown(ll x)
    {
        if(res[x])
        {
            res[x]=0;
            reser(ch[x][0]);
            reser(ch[x][1]);
        }
    }
    void down(ll x)
    {
        if(!rt[x])down(fa[x]);
        pushdown(x);
    }
    void rotate(ll x)
    {
        ll y = fa[x] , k = (ch[y][1]==x);
        if(rt[y])rt[y]=0,rt[x]=1;
        else ch[fa[y]][ch[fa[y]][1]==y] = x;
        fa[x] = fa[y];
        ch[y][k] = ch[x][!k],fa[ch[x][!k]] = y;
        ch[x][!k] = y,fa[y] = x;
        update(y),update(x);
    }
    void splay(ll x)
    {
        down(x);
        while(!rt[x])
        {
            ll y = fa[x], z = fa[y];
            if(!rt[y])
                ((ch[y][1]==x)^(ch[z][1]==y))?rotate(x):rotate(y);
            rotate(x);
        }
    }
    void access(ll x)
    {
        ll y = 0;
        while(x)
        {
            splay(x);
            sx[x]+=s[ch[x][1]];
            sx[x]-=s[y];
            rt[ch[x][1]] = 1,rt[y] = 0;
            ch[x][1] = y;
            update(x);
            y=x,x=fa[x];
        }
    }
    void mtr(ll x)
    {
        access(x);
        splay(x);
        reser(x);
    }
    void link(ll x,ll y)
    {
        mtr(x);
        access(y);
        splay(y);
        fa[x] = y;
        sx[y]+=s[x];
        update(y);
    }
    int main()
    {
        scanf("%lld%lld",&n,&m);
        for(ll i=1;i<=n;i++)rt[i]=1,s[i]=1;
        char cc[2];
        ll u,v;
        for(ll i=1;i<=m;i++)
        {
            scanf("%s%lld%lld",cc,&u,&v);
            if(cc[0]=='Q')
            {
                mtr(u);
                access(v);
                splay(u);
                printf("%lld
    ",(s[u]-s[v])*(s[v]));
            }else link(u,v);
        }
        return 0;
    }
  • 相关阅读:
    POJ 2528 Mayor's posters 线段树+离散化
    Leveldb之version与version_set详细对比
    rocksdb编译测试的正确姿势
    ycsb使用方法
    memalign vs malloc
    四种监听器(自身类,外部类,内部类,匿名类)
    数据库基础
    哈希索引和Btree索引
    哈希表hashtable
    抽象类和接口
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/9646876.html
Copyright © 2011-2022 走看看