zoukankan      html  css  js  c++  java
  • BZOJ3569 DZY Loves Chinese II(随机化+树上差分+线性基)

      上一题的强制在线版。对图跑出一个dfs树,给非树边赋上随机权值,树边的权值为覆盖他的非树边权值的异或。这样如果某条树边和覆盖他的非树边都被割掉(即图不连通),他们的异或值就为0。每次对询问看有没有子集异或值为0即可,可以简单地用线性基搞定。

    #include<iostream> 
    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int read()
    {
        int x=0,f=1;char c=getchar();
        while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
        while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
        return x*f;
    }
    #define N 100010
    #define M 500010
    int n,m,k,p[N],t=1,lastans=0;
    bool flag[N];
    unsigned long long v[M],f[N],base[64];
    struct data{int to,nxt;
    }edge[M<<1];
    void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
    void dfs(int k,int from)
    {
        flag[k]=1;
        for (int i=p[k];i;i=edge[i].nxt)
        if (edge[i].to!=from)
        {
            if (!flag[edge[i].to]) dfs(edge[i].to,k);
            else v[i>>1]=rand()+1,v[i>>1]*=rand()+1,v[i>>1]*=rand()+1,v[i>>1]*=rand()+1;
        }
    }
    void getvalue(int k)
    {
        flag[k]=1;
        for (int i=p[k];i;i=edge[i].nxt)
        if (!flag[edge[i].to])
        {
            getvalue(edge[i].to);
            v[i>>1]=f[edge[i].to];
            f[k]^=f[edge[i].to];
        }
    }
    int main()
    {
        freopen("bzoj3569.in","r",stdin);
        freopen("bzoj3569.out","w",stdout);
        n=read(),m=read();
        srand(20020509*(m/n));
        for (int i=1;i<=m;i++)
        {
            int x=read(),y=read();
            addedge(x,y),addedge(y,x);
        }
        dfs(1,1);
        for (int i=2;i<=m*2+1;i++) 
        if (i&1) f[edge[i].to]^=v[i>>1],f[edge[i^1].to]^=v[i>>1];
        memset(flag,0,sizeof(flag));
        getvalue(1);
        k=read();
        for (int i=1;i<=k;i++)
        {
            int s=read();
            memset(base,0,sizeof(base));
            bool flag=1;
            for (int j=1;j<=s;j++)
            {
                int x=read()^lastans;
                unsigned long long w=v[x];
                for (int l=63;~l;l--)
                if (w&(1ll<<l))
                {
                    if (!base[l]) {base[l]=w;break;}
                    else w^=base[l];
                }
                if (!w) flag=0;
            }
            if (flag) lastans++,printf("Connected
    ");
            else printf("Disconnected
    ");
        }
        fclose(stdin);fclose(stdout);
        return 0;
    }
  • 相关阅读:
    LeetCode OJ String to Integer (atoi) 字符串转数字
    HDU 1005 Number Sequence(AC代码)
    HDU 1004 Let the Balloon Rise(AC代码)
    HDU 1003 Max Sum(AC代码)
    012 Integer to Roman 整数转换成罗马数字
    011 Container With Most Water 盛最多水的容器
    010 Regular Expression Matching 正则表达式匹配
    007 Reverse Integer 旋转整数
    006 ZigZag Conversion
    005 Longest Palindromic Substring 最长回文子串
  • 原文地址:https://www.cnblogs.com/Gloid/p/9382450.html
Copyright © 2011-2022 走看看