zoukankan      html  css  js  c++  java
  • BZOJ:4530: [Bjoi2014]大融合

    4530: [Bjoi2014]大融合

    拿这题作为lct子树查询的练手。本来以为这会是一个大知识点,结果好像只是一个小技巧?

    多维护一个虚边连接着的子树大小即可。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define MN 210010
    using namespace std;
    
    int p,ca,f;
    inline int read(){
        p=0;ca=getchar();f=1;
        while(ca<'0'||ca>'9') {if (ca=='-') f=-1;ca=getchar();}
        while(ca>='0'&&ca<='9') p=p*10+ca-48,ca=getchar();
        return p*f;
    }
    struct na{
        int y,ne,c,nu;
    }b[MN*2];
    int fa[MN],n,t,x,y,c,num,id[MN],key[MN],ch[MN][2],ma[MN],st[MN],Si[MN],si[MN];
    bool rt[MN],rev[MN];
    inline int max(int a,int b){return a>b?a:b;}
    inline void up(int x){si[x]=si[ch[x][0]]+si[ch[x][1]]+Si[x]+1;}
    inline void pd(int x){if (rev[x]) swap(ch[x][0],ch[x][1]),rev[ch[x][0]]^=1,rev[ch[x][1]]^=1,rev[x]=0;}
    inline void rot(int x){
        int y=fa[x],kind=ch[y][1]==x;
        fa[x]=fa[y];
        fa[y]=x;
        ch[y][kind]=ch[x][!kind];
        fa[ch[y][kind]]=y;
        ch[x][!kind]=y;
        if(rt[y]) rt[y]=0,rt[x]=1;else ch[fa[x]][ch[fa[x]][1]==y]=x;
        up(y);up(x);
    }
    inline void splay(int x){
        int i=x,to=0;
        while (!rt[i]) st[++to]=i,i=fa[i];pd(i);
        for (;to;to--) pd(st[to]);
        while(!rt[x]){
            if (rt[fa[x]]) rot(x);else
            if ((ch[fa[fa[x]]][1]==fa[x])==(ch[fa[x]][1]==x)) rot(fa[x]),rot(x);else rot(x),rot(x);
        }
    }
    inline void acc(int u){
        int x=0;
        while(u){
            splay(u);
            Si[u]+=si[ch[u][1]]-si[x];
            rt[ch[u][1]]=1;rt[ch[u][1]=x]=0;
            up(u);
            u=fa[x=u];
        }
    }
    inline void root(int x){acc(x);splay(x);rev[x]^=1;}
    inline void link(int x,int y){
        root(x);acc(y);splay(y);
        fa[x]=y;Si[y]+=si[x];
    }
    inline int qu(int x,int y){
        root(x);acc(y);
        return (Si[x]+1)*(Si[y]+1);
    }
    char ss[10];
    int main(){
        n=read();t=read();
        for (int i=1;i<=n;i++) rt[i]=si[i]=1;
        while(t--){
            scanf("%s",ss);
            x=read();y=read();
            if (ss[0]=='Q') printf("%d
    ",qu(x,y));else link(x,y);
        }
    }
    View Code
  • 相关阅读:
    开发中常用js记录(二)
    c# 我所理解的 值类型 and 引用类型
    c# 枚举
    ModelState.IsValid总为false原因
    学习总结 之 WebApi服务监控 log4net记录监控日志
    How to Deinstall Oracle Clusterware Home Manually
    oracle client 低于 oracle server 端,导致报错ORA-01882
    转 zabbix 用户建立和中文化
    转 rman 恢复报错
    10g 升级到11g 失效对象2则
  • 原文地址:https://www.cnblogs.com/Enceladus/p/6726024.html
Copyright © 2011-2022 走看看