线性基
(3563是搞笑的。。。因为K也被异或,我们就可以倒推出其他答案,只要做最后一次就行了)
线性基神题
我们对原图建DFS树,这样非树边就只有返祖边了。我们给每条非树边随机一个权值,树边的权值为覆盖它的非树边权值的异或和。这样当删除的边中有异或和为0的子集时就是不连通的,这个用线性基判断。
代码:
#include<cctype>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#define N 100005
#define M 500005
#define F inline
using namespace std;
struct edge{ int nxt,to,id; }ed[M<<1];
int n,m,k,sum,ti,h[N],p[40],a[N],b[M]; bool f[N];
F char readc(){
static char buf[100000],*l=buf,*r=buf;
if (l==r) r=(l=buf)+fread(buf,1,100000,stdin);
return l==r?EOF:*l++;
}
F int _read(){
int x=0; char ch=readc();
while (!isdigit(ch)) ch=readc();
while (isdigit(ch)) x=(x<<3)+(x<<1)+(ch^48),ch=readc();
return x;
}
#define add(x,y,z) ed[++k]=(edge){h[x],y,z},h[x]=k
void dfs(int x,int fa){
f[x]=true;
for (int i=h[x],v,p;i;i=ed[i].nxt)
if ((v=ed[i].to)!=fa)
if (f[v=ed[i].to]){
if (!b[ed[i].id])
b[ed[i].id]=p=rand(),a[x]^=p,a[v]^=p;
}
else dfs(v,x),b[ed[i].id]=a[v],a[x]^=a[v];
}
F bool pd(int x){
for (int i=30;~i;i--)
if (x&(1<<i))
if (!p[i]) return p[i]=x,true;
else x^=p[i];
return x;
}
int main(){
srand(19260817); n=_read(),m=_read();
for (int i=1,x,y;i<=m;i++)
x=_read(),y=_read(),add(x,y,i),add(y,x,i);
dfs(1,0);
for (int t=_read();t;t--){
int k=_read(); bool f=true;
memset(p,0,sizeof(p));
for (int i=1,x;i<=k;i++)
if (!pd(b[_read()^sum])) f=false;
sum+=f,puts(f?"Connected":"Disconnected");
}
return 0;
}