bzoj3569
线性基
非常高端
强制在线动态图
我们先搞出一个dfs树,然后所有非树边都和树边形成一个环。我们考虑什么情况会不连通,当且仅当树边和dfs序大于当前点的返祖边都被断掉才不连通,那么我们给每个非树边赋一个权值,树边的权值就是所有这些返祖边的权值的异或和,这样一遍dfs就行了。
然后就是怎么判断,因为树边的权值等于有关非树边的异或和,那么就是当前给的边集有一个自己异或和等于0,这个可以用线性基来判断。
然后,我又在读入的时候break了,noipday1t2就因为这个调了半个小时。。。。。。
#include<bits/stdc++.h> using namespace std; const int N = 5e5 + 5; inline int rd() { 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 * 10 + c - '0'; c = getchar(); } return x * f; } struct edge { int nxt, to, w, id; } e[N << 1]; int n, m, cnt = 1, Q, ans; int head[N], c[N], w[N], vis[N], d[N], v[31]; void link(int u, int v, int id) { e[++cnt].nxt = head[u]; head[u] = cnt; e[cnt].to = v; e[cnt].id = id; } void dfs(int u, int last) { vis[u] = 1; for(int i = head[u]; i; i = e[i].nxt) if(e[i].to != last) { if(vis[e[i].to]) { if(!w[e[i].id]) { int t = rand(); w[e[i].id] = t; d[u] ^= t; d[e[i].to] ^= t; } } else { dfs(e[i].to, u); w[e[i].id] = d[e[i].to]; d[u] ^= d[e[i].to]; } } } bool check(int x) { for(int i = 30; i >= 0; --i) if(x & (1 << i)) { if(!v[i]) { v[i] = x; return 1; } else x ^= v[i]; } return x; } int main() { srand(233666); n = rd(); m = rd(); for(int i = 1; i <= m; ++i) { int u = rd(), v = rd(); link(u, v, i); link(v, u, i); } dfs(1, 0); Q = rd(); while(Q--) { int k = rd(), f = 1; memset(v, 0, sizeof(v)); for(int i = 1; i <= k; ++i) { c[i] = w[rd() ^ ans]; if(!check(c[i])) f = 0; } puts(f ? "Connected" : "Disconnected"); ans += f; } return 0; }