zoukankan      html  css  js  c++  java
  • BZOJ 3514: Codechef MARCH14 GERALD07加强版 [LCT 主席树 kruskal]

    3514: Codechef MARCH14 GERALD07加强版

    Time Limit: 60 Sec  Memory Limit: 256 MB
    Submit: 1312  Solved: 501
    [Submit][Status][Discuss]

    Description

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

    Input

    第一行四个整数N、M、K、type,代表点数、边数、询问数以及询问是否加密。
    接下来M行,代表图中的每条边。
    接下来K行,每行两个整数L、R代表一组询问。对于type=0的测试点,读入的L和R即为询问的L、R;对于type=1的测试点,每组询问的L、R应为L xor lastans和R xor lastans。

    Output

     K行每行一个整数代表该组询问的联通块个数。

    Sample Input

    3 5 4 0
    1 3
    1 2
    2 1
    3 2
    2 2
    2 3
    1 5
    5 5
    1 2

    Sample Output

    2
    1
    3
    1

    HINT

    对于100%的数据,1≤N、M、K≤200,000。

    2016.2.26提高时限至60s

    Source

    By zhonghaoxi


    刚刚去看了CreationAugust的Blog,感觉好伤感,也许我的未来就是这样吧

    这道题好神啊

    LCT维护动态最小生成树,先将每条边依次加进去,若形成环弹掉最早加进去的边,然后记录early[]数组,表示第i条边弹掉了哪条边,若没有弹出边,early[i]=0
    然后每个询问的答案就是用n减掉[l,r]区间内ntr值小于l的边的数量 可以用主席树来维护
    注意有自环

    early[i]数组记录的边不算的话i就可以贡献一个连通分量了,所以这样做

    又调了好长时间,最后发现主席树挂掉了因为以前写顺手了虽然是mid=(l+r)>>1但还是用了m...............RE一片

    最后说一下一道题用了多个大数据结构怎么办:

    1.可以用namespace

    2.宏定义是可以取消的,#undef 名字

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    #define pa t[x].fa
    #define lc t[x].ch[0]
    #define rc t[x].ch[1]
    const int N=2e5+5;
    typedef long long ll;
    inline int read(){
        char c=getchar();int x=0,f=1;
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x*f;
    }
    
    int n,m,Q,type;
    struct LCTnode{
        int ch[2],fa,rev,w,mx,p;
    }t[N<<1];
    inline int wh(int x){return t[pa].ch[1]==x;}
    inline int isRoot(int x){return t[pa].ch[0]!=x&&t[pa].ch[1]!=x;}
    inline void update(int x){
        t[x].mx=t[x].w;t[x].p=x;
        if(t[lc].mx>t[x].mx) t[x].mx=t[lc].mx,t[x].p=t[lc].p;
        if(t[rc].mx>t[x].mx) t[x].mx=t[rc].mx,t[x].p=t[rc].p;
    }
    inline void rever(int x){
        t[x].rev^=1;
        swap(lc,rc);
    }
    inline void pushDown(int x){
        if(t[x].rev){
            rever(lc);
            rever(rc);
            t[x].rev=0;    
        }
    }
    inline void rotate(int x){
        int f=t[x].fa,g=t[f].fa,c=wh(x);
        if(!isRoot(f)) t[g].ch[wh(f)]=x;t[x].fa=g;
        t[f].ch[c]=t[x].ch[c^1];t[t[f].ch[c]].fa=f;
        t[x].ch[c^1]=f;t[f].fa=x;
        update(f);update(x);
    }
    int st[N],top;
    inline void splay(int x){
        top=0;st[++top]=x;
        for(int i=x;!isRoot(i);i=t[i].fa) st[++top]=t[i].fa;
        for(int i=top;i>=1;i--) pushDown(st[i]);
        
        for(;!isRoot(x);rotate(x))
            if(!isRoot(pa)) rotate(wh(x)==wh(pa)?pa:x);
    }
    inline void Access(int x){
        for(int y=0;x;y=x,x=pa){
            splay(x);
            rc=y;
            update(x);
        }
    }
    inline void MakeR(int x){
        Access(x);splay(x);
        rever(x);
    }
    inline int FindR(int x){
        Access(x);splay(x);
        while(lc) x=lc;
        return x;
    }
    inline void Link(int x,int y){
        MakeR(x);
        t[x].fa=y;
    }
    inline void Cut(int x,int y){
        MakeR(x);Access(y);splay(y);
        t[y].ch[0]=t[x].fa=0;
        update(y);//!!!
    }
    inline void Split(int x,int y){
        MakeR(x);Access(y);splay(y);
    }
    inline int Que(int x,int y){
        MakeR(x);Access(y);splay(y);
        return t[y].p;
    }
    
    struct edge{
        int u,v;
    }e[N];
    int early[N];
    void Kruskal(){
        for(int i=1;i<=m;i++){//printf("kru %d
    ",i);
            int u=e[i].u,v=e[i].v;
            if(u==v) {early[i]=i;continue;}
            if(FindR(u)==FindR(v)){
                int p=Que(u,v);
                early[i]=p-n;
                Cut(e[p-n].u,p);Cut(e[p-n].v,p);
            }
            Link(u,i+n);Link(v,i+n);
        }
    }
    
    #undef lc
    #undef rc
    #define lc(x) t[x].l
    #define rc(x) t[x].r
    namespace F{
        struct Fnode{
            int l,r,size;
        }t[N*30];
        int sz=0,root[N];
        void ins(int &x,int l,int r,int p){
            t[++sz]=t[x]; x=sz;
            t[x].size++;
            if(l==r) return;
            int mid=(l+r)>>1;
            if(p<=mid) ins(t[x].l,l,mid,p);
            else ins(t[x].r,mid+1,r,p);
        }
        int que(int x,int y,int l,int r,int ql,int qr){//printf("que %d %d %d %d
    ",l,r,ql,qr);
            if(ql<=l&&r<=qr) return t[y].size-t[x].size;
            else{
                int m=(l+r)>>1,ans=0;
                if(ql<=m) ans+=que(lc(x),lc(y),l,m,ql,qr);
                if(m<qr) ans+=que(rc(x),rc(y),m+1,r,ql,qr);
                return ans;
            }
        }
        int l,r,lastans=0;
        void solve(){
            for(int i=1;i<=m;i++) root[i]=root[i-1],ins(root[i],0,m,early[i]);
            //for(int i=0;i<=m;i++) printf("root %d
    ",root[i]); 
            while(Q--){
                l=read();r=read();
                if(type) l^=lastans,r^=lastans;
                lastans=n-que(root[l-1],root[r],0,m,0,l-1);
                printf("%d
    ",lastans);
            }
        }
    }
    int main(){
        //freopen("in.txt","r",stdin);
        n=read();m=read();Q=read();type=read();
        for(int i=1;i<=m;i++){
            e[i].u=read(),e[i].v=read();
            t[i+n].w=t[i+n].mx=m+n-i+1;
            t[i+n].p=i+n;
        }
        Kruskal();
        F::solve();
    }

     

  • 相关阅读:
    深入Android 【一】 —— 序及开篇
    Android中ContentProvider和ContentResolver使用入门
    深入Android 【六】 —— 界面构造
    The service cannot be activated because it does not support ASP.NET compatibility. ASP.NET compatibility is enabled for this application. Turn off ASP.NET compatibility mode in the web.config or add the AspNetCompatibilityRequirements attribute to the ser
    Dynamic Business代码片段总结
    对文件的BuildAction以content,resource两种方式的读取
    paraview 3.12.0 windows下编译成功 小记
    百度网盘PanDownload使用Aria2满速下载
    netdata的安装与使用
    用PS给证件照排版教程
  • 原文地址:https://www.cnblogs.com/candy99/p/6279791.html
Copyright © 2011-2022 走看看