[BZOJ3569]DZY Loves Chinese II 哈希+线性基

拿出原图的一个生成树
那么一个图不连通当且仅当切断了某一段的树边和所有覆盖这一段的非树边
给所有的非树边一个随机的哈希值,树边的哈希值为所有覆盖它的非树边的哈希值的异或和
若一条树边以及所有覆盖它的非树边被移除了,那么这些边的异或和为0
我们用线性基实现查询询问是否存在一个子集异或和为0

#include <bits/stdc++.h>
#define N 100050
#define M 1000050

#define each(v) for (int i=h[u],v; v=e[i].b,i; i=e[i].n)

using namespace std;
typedef unsigned long long uLL;
struct Edge{ int a,b,n; }e[2*M];
uLL hash[M],tmp[M];
int h[N],vis[N],cnt=1,n,m;
int flag;
uLL F[65];

inline int rd() { int r; scanf("%d",&r); return r; }
void link(int x,int y) {
    e[++cnt] = (Edge){x,y,h[x]}, h[x] = cnt;
    e[++cnt] = (Edge){y,x,h[y]}, h[y] = cnt;
}
uLL rnd() { return (((uLL)rand())<<32)^((uLL)rand()<<16) ^ rand(); }
void dfs1(int u,int f) {
    vis[u] = 1;
    each(v) if (v != f) {
        if (!vis[v]) dfs1(v,u); else hash[i>>1] = rnd();
    }
}

void dfs2(int u,int f) {
    vis[u] = 1;
    each(v) if (v != f && !vis[v]) {
        dfs2(v,u);
        tmp[u] ^= tmp[v];
        hash[i>>1] = tmp[v];
    }
}

void add(uLL x) {
    for (int i=60;i>=0;i--) {
        x == 0 ? flag = 1 : 0;
        if ((x>>i)&1) {
            if (!F[i]) { F[i] = x; break; } else x ^= F[i];
        }
    }
}

int main() {
    #ifndef ONLINE_JUDGE
        freopen("1.in","r",stdin);
    #endif
    srand(19930726);
    n = rd(), m = rd();
    for (int _=1;_<=m;_++) link(rd(),rd());
    memset(vis,0,sizeof(vis));
    dfs1(1,1);

    for (int _=1;_<=m;_++)
        tmp[e[_<<1].a] ^= hash[_], tmp[e[_<<1].b] ^= hash[_];

    memset(vis,0,sizeof(vis));
    dfs2(1,1);

    int q=rd(), ans = 0;
    while (q--) {
        int k = rd(); flag = 0;
        for (int _=0;_<=60;_++) F[_] = 0LL;
        for (int _=1;_<=k;_++) add( hash[rd()^ans] );
        !flag ? ans++, puts("Connected") : puts("Disconnected");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值