BZOJ3569: DZY Loves Chinese II(BZOJ3563)

版权声明:蒟蒻Blog随意转载 https://blog.csdn.net/a1799342217/article/details/82968517

线性基

BZOJ3569
BZOJ3563

(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;
}

猜你喜欢

转载自blog.csdn.net/a1799342217/article/details/82968517
今日推荐