zoukankan      html  css  js  c++  java
  • bzoj3514(LCT+主席树)

    题目描述

    N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数。

    题解

    对于一个截止时间来说,越晚的变越好。

    所以我们可以维护一颗以边的序号为关键字的最大生成树,然后用主席树维护一下。

    询问直接在R的主席树里查就可以了。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define N 400002
    using namespace std;
    int f[N],a[N],n,m,type,k;
    inline int rd(){
        int x=0;char c=getchar();bool f=0;
        while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
        while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        return f?-x:x;
    } 
    inline int find(int x){return f[x]=f[x]==x?x:find(f[x]);}
    struct LCT{
        int ch[N][2],fa[N],l[N],tr[N];bool rev[N];
        #define ls ch[x][0]
        #define rs ch[x][1]
        inline bool ge(int x){return ch[fa[x]][1]==x;}
        inline bool isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
        inline void pushup(int x){
            tr[x]=x;
            if(ls&&a[tr[ls]]<a[tr[x]])tr[x]=tr[ls];if(rs&&a[tr[rs]]<a[tr[x]])tr[x]=tr[rs];
        }
        inline void rotate(int x){
            int y=fa[x],o=ge(x);
            ch[y][o]=ch[x][o^1];fa[ch[y][o]]=y;
            if(!isroot(y))ch[fa[y]][ge(y)]=x;fa[x]=fa[y];
            fa[y]=x;ch[x][o^1]=y;pushup(y);pushup(x);
        }
        inline void pushdown(int x){if(rev[x]){rev[x]^=1;rev[ls]^=1;rev[rs]^=1;swap(ls,rs);}}
        inline void _pushdown(int x){if(!isroot(x))_pushdown(fa[x]);pushdown(x);}
        inline void splay(int x){
            _pushdown(x);
            while(!isroot(x)){
                int y=fa[x];
                if(isroot(y))rotate(x);
                else rotate(ge(x)==ge(y)?y:x),rotate(x);
            }
        }
        inline int findroot(int x){
            access(x);splay(x);pushdown(x);
            while(ls)x=ls,pushdown(x);return x;
        }
        inline void access(int x){for(int y=0;x;y=x,x=fa[x])splay(x),ch[x][1]=y,pushup(x);}
        inline void makeroot(int x){access(x);splay(x);rev[x]^=1;}
        inline void split(int x,int y){makeroot(x);access(y);splay(y);}
        inline void link(int x,int y){makeroot(x);fa[x]=y;}
        inline void cut(int x,int y){split(x,y);fa[x]=ch[y][0]=0;pushup(y);}
        void dfs(int x){
            if(ls)dfs(ls);cout<<x<<" ";if(rs)dfs(rs);
        }
        #undef ls
        #undef rs
    }lct;
    int tot,ls[N*20],rs[N*20],sum[N*20],T[N],ans;
    void upd(int &cnt,int pre,int l,int r,int x,int y){
        cnt=++tot;ls[cnt]=ls[pre];rs[cnt]=rs[pre];sum[cnt]=sum[pre]+y;
        if(l==r)return;
        int mid=(l+r)>>1;
        if(mid>=x)upd(ls[cnt],ls[pre],l,mid,x,y);
        else upd(rs[cnt],rs[pre],mid+1,r,x,y);
    }
    int query(int cnt,int l,int r,int L,int R){
        if(l>=L&&r<=R)return sum[cnt];
        int mid=(l+r)>>1,ans=0;
        if(mid>=L)ans+=query(ls[cnt],l,mid,L,R);
        if(mid<R)ans+=query(rs[cnt],mid+1,r,L,R);
        return ans;
    }
    struct edge{int x,y;}b[N];
    int main(){
        n=rd();m=rd();k=rd();type=rd();
        for(int i=1;i<=n;++i)f[i]=i;int x,y;
        for(int i=1;i<=n;++i)a[i]=2e9;
        for(int i=1;i<=m;++i){
            a[i+n]=i;
            x=rd();y=rd();T[i]=T[i-1];b[i].x=x;b[i].y=y;
            if(x==y)continue;
            if(find(x)==find(y)){
                lct.split(x,y);
                int id=lct.tr[y];
            //    lct.dfs(y);cout<<" ??? "<<x<<" "<<y<<" "<<id<<" "<<lct.findroot(y)<<endl;
                lct.cut(id,b[id-n].x);lct.cut(id,b[id-n].y);upd(T[i],T[i],1,m,id-n,-1);
                lct.link(x,i+n);lct.link(y,i+n);
            }else{
              lct.link(x,i+n);lct.link(y,i+n);
              int xx=find(x),yy=find(y);f[xx]=yy; 
            }
            upd(T[i],T[i],1,m,i,1);
        }
        for(int i=1;i<=k;++i){
            x=rd();y=rd();if(type)x^=ans,y^=ans;
            printf("%d
    ",ans=n-query(T[y],1,m,x,y));
        }
        return 0;
    }
  • 相关阅读:
    对webpack的初步研究7
    对后端返回的时间进行升序的排序
    对webpack的初步研究6
    对webpack的初步研究5
    对webpack的初步研究4
    对webpack的初步研究3
    计算两个时间之间的天数、小时等
    对webpack的初步研究2
    线程_进程间通信Queue合集
    线程_threading合集
  • 原文地址:https://www.cnblogs.com/ZH-comld/p/10225724.html
Copyright © 2011-2022 走看看