zoukankan      html  css  js  c++  java
  • [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;
    }
    

      

  • 相关阅读:
    [BZOJ]2132: 圈地计划 最小割
    从最近MySQL的优化工作想到的
    Linux基本操作 9----- 认识与学习bash
    多路径配置vlome group共享存储,VG的更新。
    两位数乘法的速算方法(一)
    请对他有足够的重视——设计!
    ASP.NET中配置应用程序
    flex开发小技巧集锦
    刚制作完的SAP Sybase ASE15.7 [Sybase Central] 客户端
    Static 关键字的 5 种用法,你会几种?
  • 原文地址:https://www.cnblogs.com/guangheli/p/10110540.html
Copyright © 2011-2022 走看看