• BZOJ 3569: DZY Loves Chinese II [高斯消元XOR 神题]


    http://www.lydsy.com/JudgeOnline/problem.php?id=3569

    题意:多次询问一个无向连通图当图中某k条边消失时这个图是否联通 强制在线


    太神啦啦啦啦啦啦啦啦啦拉拉啦啦啦啦

    求一棵生成树,给所有的非树边随机分配一个权值,树边的权值为所有覆盖它的非树边的权值的异或和

    这样做之后,去掉k条边后原图不连通,当且仅当k条边的一个子集权值异或和为0

    只有树边和覆盖它的非树边都消失了或者根本没有非树边才会造成非联通

    因为权值是随机的,冲突的可能性很小....

    求线性基就好了

    如何计算树边的权值?

    首先一个点异或上所有与他相连的非树边,然后一条树边u--->v的权值就是v子树点值异或和

    注意:

    1.分配非树边要记录$fa$因为有可能把与$fa$相连的边给分配了

    2.我一直纠结于邻接表边从$1$开始编号然后正向边和反向边$>>1$结果不同,然后发现只要邻接表从$2$开始就好了

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <bitset>
    using namespace std;
    typedef long long ll;
    const int N=1e5+5,M=5e5+5,INF=1e9;
    inline int read(){
        char c=getchar();int x=0;
        while(c<'0'||c>'9'){c=getchar();}
        while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
        return x;
    }
    int n,m,u,v,Q,cntans;
    int a[20],p,bin[32];
    void ini(){
        for(int i=0;i<=30;i++) bin[i]=1<<i;
    }
    struct edge{
        int v,ne;
    }e[M<<1];
    int h[N],cnt=1;//magic
    inline void ins(int u,int v){
        cnt++;
        e[cnt].v=v;e[cnt].ne=h[u];h[u]=cnt;
        cnt++;
        e[cnt].v=u;e[cnt].ne=h[v];h[v]=cnt;
    }
    bool vis[N];
    int w[M],d[N];
    void dfs(int u,int fa){
        vis[u]=1;
        for(int i=h[u];i;i=e[i].ne){
            int v=e[i].v;
            if(v==fa) continue;
            if(!vis[v]) dfs(v,u);
            else if(!w[i>>1]){
                w[i>>1]=rand();
                d[u]^=w[i>>1];
                d[v]^=w[i>>1];
            }
        }
    }
    void dfs2(int u){
        vis[u]=1;
        for(int i=h[u];i;i=e[i].ne){
            int v=e[i].v;
            if(vis[v]) continue;
            dfs2(v);
            d[u]^=d[v];
            w[i>>1]=d[v];
        }
    }
    int now;
    void Gauss(int n){
        now=1;
        for(int i=30;i>=0;i--){
            int j=now;
            while(j<=n&&!(a[j]&bin[i])) j++;
            if(j==n+1) continue;
            if(j!=now) swap(a[now],a[j]);
            for(int k=1;k<=n;k++)
                if(k!=now&&(a[k]&bin[i])) a[k]^=a[now];
            now++;
        }
        now--;
    }
    
    int main(){
        freopen("in","r",stdin);
        srand(219);
        ini();
        n=read();m=read();
        for(int i=1;i<=m;i++) u=read(),v=read(),ins(u,v);
        dfs(1,0);
        //for(int i=1;i<=m;i++) printf("w %d %d
    ",i,w[i]);
        memset(vis,0,sizeof(vis));
        dfs2(1);
        //for(int i=1;i<=m;i++) printf("w %d %d
    ",i,w[i]);
        Q=read();
        while(Q--){
            int k=read();p=0;int x;
            while(k--) x=read(),a[++p]=w[x^cntans];//,printf("x %d %d %d
    ",x,cntans,x^cntans);
            //for(int i=1;i<=p;i++) printf("a %d %d
    ",i,a[i]);
            Gauss(p);
            //printf("now %d %d
    ",now,p);
            if(now<p) puts("Disconnected");
            else cntans++,puts("Connected");
        }
    }
  • 相关阅读:
    C#随机数的使用
    英才评测 个人性格倾向 IT知识
    有点迷茫
    [转帖]2006年it人士必去的10个网站
    ASP.NET 中 Cookie 的基本知识
    Http请求方法
    Spherical Mercator
    Axure快速原型设计
    【转】Spring Insight 使用介绍
    DB2执行sql文件
  • 原文地址:https://www.cnblogs.com/candy99/p/6416442.html
Copyright © 2020-2023  润新知