zoukankan      html  css  js  c++  java
  • BZOJ3514 Codechef MARCH14 GERALD07加强版 LCT+可持久化线段树

    联通块个数等于 $n$ 减掉关键边个数.  

    这里定义关键边为:能连接两个连通块的边.     

    由于强制在线,我们考虑用一种数据结构维护以 $r$ 为右端点的答案.     

    考虑已经构建好 $1$ ~ $r-1$ 的图,那么假如 $r$ 时分两种情况:   

    1. $r$ 连接的两个点没有联通,那么就将这两个点连上.

    2. $r$ 连接的两个点已经联通,那么以 $r$ 为询问的右端点的话不论 $l$ 取什么 $u,v$ 都联通.    

    为了后面的维护,关键边的开始时间显然越靠后越好,那么在情况 $2$ 中直接删掉开始时间最小的边即可.     

    关键边用主席树来维护贡献,询问的时候在主席树中查询区间和即可.    

    #include <bits/stdc++.h>
    #define N 400005  
    #define inf 1000000000
    #define setIO(s) freopen(s".in","r",stdin) , freopen(s".out","w",stdout) 
    using namespace std; 
    int rt[N];    
    struct Edge
    {
        int u,v,c; 
        Edge(int u=0,int v=0,int c=0):u(u),v(v),c(c){} 
    }e[N];  
    struct Union_Find_set
    {
        int p[N];  
        void init() 
        {
            for(int i=0;i<N;++i) p[i]=i; 
        }
        int find(int x) 
        {
            return p[x]==x?x:p[x]=find(p[x]); 
        }
        int merge(int x,int y) 
        {
            x=find(x),y=find(y); 
            if(x!=y) 
            {
                p[x]=y; 
                return 1; 
            }
            else 
            {
                return 0; 
            }
        }
    }ufs; 
    struct Link_Cut_Tree
    {
        #define lson t[x].ch[0] 
        #define rson t[x].ch[1] 
        int sta[N];  
        struct Node 
        {
            int ch[2],f,min,id,val,rev;  
        }t[N];
        int get(int x) 
        {
            return t[t[x].f].ch[1]==x;  
        }
        int isrt(int x) 
        {
            return !(t[t[x].f].ch[0]==x||t[t[x].f].ch[1]==x); 
        }
        void pushup(int x) 
        {
            t[x].min=t[x].val,t[x].id=x;   
            if(lson&&t[lson].min<t[x].min) t[x].min=t[lson].min,t[x].id=t[lson].id; 
            if(rson&&t[rson].min<t[x].min) t[x].min=t[rson].min,t[x].id=t[rson].id;   
        }
        void mark(int x) 
        {
            if(x) t[x].rev^=1,swap(lson,rson); 
        }
        void pushdown(int x) 
        {
            if(x&&t[x].rev) 
            {
                t[x].rev=0; 
                if(lson) mark(lson); 
                if(rson) mark(rson);   
            }
        }
        void rotate(int x) 
        {
            int old=t[x].f,fold=t[old].f,which=get(x); 
            if(!isrt(old)) t[fold].ch[t[fold].ch[1]==old]=x; 
            t[old].ch[which]=t[x].ch[which^1],t[t[old].ch[which]].f=old;  
            t[x].ch[which^1]=old,t[old].f=x,t[x].f=fold; 
            pushup(old),pushup(x); 
        }
        void splay(int x) 
        {
            int v=0,u=x,fa;
            for(sta[++v]=u;!isrt(u);u=t[u].f) sta[++v]=t[u].f;  
            for(;v;--v) pushdown(sta[v]);   
            for(u=t[u].f;(fa=t[x].f)!=u;rotate(x)) 
                if(t[fa].f!=u) 
                    rotate(get(fa)==get(x)?fa:x);  
        }
        void Access(int x) 
        {
            for(int y=0;x;y=x,x=t[x].f) 
                splay(x),rson=y,pushup(x); 
        }
        void makeroot(int x) 
        {
            Access(x),splay(x),mark(x); 
        }
        void split(int x,int y) 
        {
            makeroot(x),Access(y),splay(y); 
        }
        void link(int x,int y) 
        {
            makeroot(x),t[x].f=y; 
        }
        void cut(int x,int y) 
        {
            makeroot(x),Access(y),splay(y);   
            t[y].ch[0]=t[x].f=0; 
            pushup(y); 
        }
        #undef lson 
        #undef rson
    }lct; 
    struct Segment_Tree
    {
        int tot;  
        int lson[N*20],rson[N*20],sum[N*20];  
        int update(int x,int l,int r,int p,int d) 
        {
            int oo=++tot;    
            lson[oo]=lson[x],rson[oo]=rson[x],sum[oo]=sum[x]+d;  
            if(l==r) return oo; 
            int mid=(l+r)>>1;   
            if(p<=mid) lson[oo]=update(lson[x],l,mid,p,d);
            else rson[oo]=update(rson[x],mid+1,r,p,d); 
            return oo; 
        }
        int query(int x,int l,int r,int L,int R) 
        {
            if(!x) return 0; 
            if(l>=L&&r<=R) return sum[x]; 
            int mid=(l+r)>>1,re=0;   
            if(L<=mid) re+=query(lson[x],l,mid,L,R); 
            if(R>mid)  re+=query(rson[x],mid+1,r,L,R); 
            return re; 
        }
    }tr; 
    int main() 
    {
        // setIO("input"); 
        int n,m,i,j,k,ty; 
        scanf("%d%d%d%d",&n,&m,&k,&ty); 
        lct.t[0].val=inf;      
        for(i=1;i<=n;++i) lct.t[i].val=inf,lct.pushup(i); 
        ufs.init();  
        for(i=1;i<=m;++i) 
        {
            scanf("%d%d",&e[i].u,&e[i].v);     
            int u=e[i].u;
            int v=e[i].v;
            int _new=i+n; 
            rt[i]=rt[i-1];  
            if(u==v) 
            {
                continue;
            }  
            rt[i]=tr.update(rt[i-1],1,m,i,1);        
            if(ufs.merge(u,v)) 
            {  
                lct.t[_new].val=i; 
                lct.pushup(_new);    
                lct.link(u,_new); 
                lct.link(_new,v);   
            }
            else
            {
                lct.split(u,v);   
                int cc=lct.t[v].id;    
                lct.cut(cc, e[cc-n].u);  
                lct.cut(cc, e[cc-n].v);      
                rt[i]=tr.update(rt[i],1,m,cc-n,-1);  
                lct.t[_new].val=i;  
                lct.pushup(_new);      
                lct.link(_new, u);  
                lct.link(_new, v);   
            }
        }
        int lastans=0;
        for(i=1;i<=k;++i) 
        {
            int l,r; 
            scanf("%d%d",&l,&r); 
            if(ty) 
            {
                l^=lastans; 
                r^=lastans; 
                if(l>r) swap(l,r); 
            }
            lastans=n-tr.query(rt[r],1,m,l,r);   
            printf("%d
    ",lastans);  
        }
        return 0; 
    }
    

      

  • 相关阅读:
    Python使用inspect查看代码参数
    Python的hasattr() getattr() setattr()
    Module-GitBook使用手册
    Module-Hadoop技术文档
    Module-Git使用手册
    Module-Faker使用手册
    Module-Docker使用手册
    Module-DB2技术文档
    Module-Dask并行任务调度
    Module-Apache使用说明
  • 原文地址:https://www.cnblogs.com/guangheli/p/11588323.html
Copyright © 2011-2022 走看看