BZOJ3569: DZY Loves Chinese II(BZOJ3563)
阿新 • • 發佈:2018-12-14
線性基
(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;
}