• [BJOI2014]大融合 LCT维护子树信息


    Code:

    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <string>
    using namespace std;
    void setIO(string a){freopen((a+".in").c_str(),"r",stdin);}
    
    #define maxn 100009
    #define ll long long
    int n,q;
    struct LCT{
        int ch[maxn][2],f[maxn],siz[maxn],sta[maxn],son[maxn],tag[maxn];
        int lson(int x){ return ch[x][0]; }
        int rson(int x){ return ch[x][1]; }
        int get(int x){ return ch[f[x]][1]==x;}
        int isRoot(int x){ return !(ch[f[x]][0]==x||ch[f[x]][1]==x); }
        void mark(int x){ if(!x)return; swap(ch[x][0],ch[x][1]),tag[x]^=1; }
        void pushdown(int x){ if(tag[x]) mark(lson(x)),mark(rson(x)),tag[x]=0; }
        void pushup(int x){ if(!x) return; siz[x]=siz[lson(x)]+siz[rson(x)]+son[x]+1; }
    
        void rotate(int x){
            int old=f[x],fold=f[old],which=get(x);
            if(!isRoot(old)) ch[fold][ch[fold][1]==old]=x; 
            ch[old][which]=ch[x][which^1],f[ch[old][which]]=old;
            ch[x][which^1]=old,f[old]=x,f[x]=fold;
            pushup(old),pushup(x); 
        }
        void splay(int x){
            int v=0,u=x;
            sta[++v]=u;
            while(!isRoot(u)) sta[++v]=f[u],u=f[u];
            while(v) pushdown(sta[v--]);
            u=f[u];
            for(int fa;(fa=f[x])!=u;rotate(x))
                if(f[fa]!=u) rotate(get(fa)==get(x)?fa:x);
        }
        void Access(int x){for(int y=0;x;y=x,x=f[x]) splay(x),son[x]=son[x]+siz[ch[x][1]]-siz[y], ch[x][1]=y, pushup(x);  }
        void makeRoot(int x){ Access(x), splay(x), mark(x);}
        void link(int a,int b){ makeRoot(a), makeRoot(b), son[a]+=siz[b], f[b]=a,  pushup(a); }
        ll query(int a,int b){
            makeRoot(a),makeRoot(b); 
            return (long long)siz[a]*(siz[b]-siz[a]);
        }
    }tree;
    int main(){
        //setIO("input");
        int a,b;
        char opt[5];
        scanf("%d%d",&n,&q);
        while(q--){
            scanf("%s%d%d",opt,&a,&b);
            switch(opt[0]){
                case 'A': {
                    tree.link(a,b);
                    break;
                }
                case 'Q': {
                    printf("%lld
    ",tree.query(a,b));
                    break;
                }
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    js 类对象
    图片自动轮播及点击图标切换图片
    js 常用方法
    js-案例 国家-省市-区域之间的三级联动
    JS 基础知识之传智播客2
    JS 基础知识之传智播客1
    div居中
    formatDate 格式化日期 ,给小于10的月日,加0,如01 02 03
    Radiobutton改成文字样式
    如何在Android平台下进行Socket通信
  • 原文地址:https://www.cnblogs.com/guangheli/p/10110540.html
Copyright © 2020-2023  润新知