• bzoj4530 [Bjoi2014]大融合


    Description

    小强要在N个孤立的星球上建立起一套通信系统。这套通信系统就是连接N个点的一个树。
    这个树的边是一条一条添加上去的。在某个时刻,一条边的负载就是它所在的当前能够
    联通的树上路过它的简单路径的数量。
    例如,在上图中,现在一共有了5条边。其中,(3,8)这条边的负载是6,因
    为有六条简单路径2-3-8,2-3-8-7,3-8,3-8-7,4-3-8,4-3-8-7路过了(3,8)。
    现在,你的任务就是随着边的添加,动态的回答小强对于某些边的负载的
    询问。

    Input

    第一行包含两个整数N,Q,表示星球的数量和操作的数量。星球从1开始编号。
    接下来的Q行,每行是如下两种格式之一:
    A x y 表示在x和y之间连一条边。保证之前x和y是不联通的。
    Q x y 表示询问(x,y)这条边上的负载。保证x和y之间有一条边。
    1≤N,Q≤100000

    Output

    对每个查询操作,输出被查询的边的负载。

    树链剖分预处理所有操作完成后的森林,树状数组维护区间和,按顺序处理询问和修改,用并查集维护连通性和当前每棵树的根

    对询问a,b,若fa[b]=a则ans= b的子树大小*(a,b所在树的大小-b的子树大小)

    复杂度O(qlog2n)

    #include<cstdio>
    inline int read(){
        int x=0,c=getchar();
        while(c>57||c<48)c=getchar();
        while(c>47&&c<58)x=x*10+c-48,c=getchar();
        return x;
    }
    inline char readchr(){
        int c=getchar();
        while(c!='A'&&c!='Q')c=getchar();
        return c;
    }
    const int N=100005;
    int n,q,M;
    int f[N],bit[N];
    int qo[N],q1[N],q2[N];
    int es[N*2],enx[N*2],e0[N],ep=2;
    int dep[N],sz[N],fa[N],son[N],top[N],id[N],idp=1;
    inline void inc(int x,int y){
        while(x<M)bit[x]+=y,x+=x&-x;
    }
    inline int sum(int x){
        int s=0;
        while(x)s+=bit[x],x-=x&-x;
        return s+1;
    }
    inline void addedge(int x,int y){
        es[ep]=y;enx[ep]=e0[x];e0[x]=ep++;
        es[ep]=x;enx[ep]=e0[y];e0[y]=ep++;
    }
    void f1(int w,int pa){
        fa[w]=pa;
        sz[w]=1;
        for(int i=e0[w];i;i=enx[i]){
            int u=es[i];
            if(u==pa)continue;
            dep[u]=dep[w]+1;
            f1(u,w);
            sz[w]+=sz[u];
            if(sz[u]>sz[son[w]])son[w]=u;
        }
    }
    void f2(int w,int tp){
        id[w]=idp++;
        top[w]=tp;
        if(son[w])f2(son[w],tp);
        for(int i=e0[w];i;i=enx[i]){
            int u=es[i];
            if(u!=fa[w]&&u!=son[w])f2(u,u);
        }
    }
    inline void modify(int x,int y,int v){
        int a=top[x],b=top[y];
        while(a!=b){
            inc(id[x]+1,-v);
            inc(id[a],v);
            x=fa[a];a=top[x];
        }
        inc(id[x]+1,-v);
        inc(id[y],v);
    }
    inline int get(int x){
        int a=x,c;
        while(x!=f[x])x=f[x];
        while(x!=(c=f[a]))f[a]=x,a=c;
        return x;
    }
    int main(){
        n=read();q=read();
        M=n+2;
        for(int i=0;i<q;i++){
            qo[i]=readchr();
            q1[i]=read();q2[i]=read();
            if(qo[i]=='A')addedge(q1[i],q2[i]);
        }
        for(int i=1;i<=n;i++)f[i]=i;
        for(int i=1;i<=n;i++)if(!id[i]){
            f1(i,0);
            f2(i,i);
        }
        for(int i=0;i<q;i++){
            int o=qo[i],a=q1[i],b=q2[i];
            if(o=='A'){
                int c=get(a),d=get(b);
                if(dep[c]<dep[d]){
                    modify(a,c,sum(id[b]));
                    f[d]=c;
                }else{
                    modify(b,d,sum(id[a]));
                    f[c]=d;
                }
            }else{
                if(dep[a]<dep[b]){
                    int s=sum(id[b]);
                    printf("%lld
    ",s*1ll*(sum(id[get(a)])-s));
                }else{
                    int s=sum(id[a]);
                    printf("%lld
    ",s*1ll*(sum(id[get(b)])-s));
                }
            }
        }
        return 0;
    }

    理论上lct复杂度更小...

  • 相关阅读:
    试试SQLServer 2014的内存优化表
    备份数据库的时候设置 BufferCount 选项不正确导致 out of memory 的情况
    SQLSERVER复制优化之一《改变包大小》
    Tomcat配置域名和虚拟文件夹
    BZOJ 1798 [Ahoi2009]Seq 维护序列seq 线段树
    125 Valid Palindrome
    jquery.lazyload.js实现图片懒载入
    hdu 2176 取石子游戏
    算法练习--十进制 二进制互转
    JavaScript学习10:动态载入脚本和样式
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5396596.html
Copyright © 2020-2023  润新知