• [BZOJ3563&3569]DZY Loves Chinese


    bzoj
    加强版

    sol

    其实前一题还有一种解法的,具体方法请见bzoj讨论版。
    以下是正解(?)
    建一棵生成树。
    考虑什么时候图会不连通:当且仅当存在一条树边被删除,同时所有覆盖了他的非树边也被删除。
    所以考虑给每条非树边随机一个权值,然后把每条树边的权值设为所以覆盖了这条边的非树边的边权异或和。
    这样一来在要删除的边集中,若存在一个异或和为零的子集则说明图会不连通。
    线性基维护一下。复杂度(O(n+Qk*30))

    code

    我WA了半天结果是随机种子出锅了。。。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<ctime>
    using namespace std;
    int gi()
    {
    	int x=0,w=1;char ch=getchar();
    	while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    	if (ch=='-') w=0,ch=getchar();
    	while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    	return w?x:-x;
    }
    const int N = 1e6+5;
    int n,m,q,to[N],nxt[N],id[N],head[N],cnt,fa[N],val[N],tag[N],ans;
    int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
    void link(int u,int v,int w)
    {
    	to[++cnt]=v;nxt[cnt]=head[u];id[cnt]=w;
    	head[u]=cnt;
    }
    void dfs(int u,int f)
    {
    	for (int e=head[u];e;e=nxt[e])
    		if (to[e]!=f)
    		{
    			dfs(to[e],u);
    			val[id[e]]^=tag[to[e]];
    			tag[u]^=tag[to[e]];
    		}
    }
    struct xxj{
    	int p[32];
    	void init(){memset(p,0,sizeof(p));}
    	void insert(int x)
    		{
    			for (int j=30;~j;--j)
    			{
    				if (!(x>>j)) continue;
    				if (!p[j]) {p[j]=x;return;}
    				x^=p[j];
    			}
    		}
    	int query(int x)
    		{
    			for (int j=30;~j;--j)
    				x=min(x,x^p[j]);
    			return x;
    		}
    }S;
    int main()
    {
    	srand(2002415);
    	n=gi();m=gi();
    	for (int i=1;i<=n;++i) fa[i]=i;
    	for (int i=1;i<=m;++i)
    	{
    		int u=gi(),v=gi();
    		if (find(u)^find(v))
    			link(u,v,i),link(v,u,i),fa[find(u)]=find(v);
    		else val[i]=1+rand()%(1<<30),tag[u]^=val[i],tag[v]^=val[i];
    	}
    	dfs(1,0);
    	q=gi();
    	while (q--)
    	{
    		int k=gi()^ans,fg=1;S.init();
    		for (int i=1;i<=k;++i)
    		{
    			int x=gi()^ans;
    			if (S.query(val[x])) S.insert(val[x]);
    			else fg=0;
    		}
    		puts(fg?"Connected":"Disconnected");ans+=fg;
    	}
    	return 0;
    }
    
  • 相关阅读:
    Windows10如何删除“极速输入法”?
    python 递归实现 冒泡排序
    leetcode 912
    python 快速排序
    python 选择排序
    python 使用递归法对整数进行因数分解
    用函数嵌套定义和递归实现帕斯卡公式C(n,i) = C(n-1, i) + C(n-1, i-1), 进行组合数C(n,i)的快速求解。
    L2-3 清点代码库 (25 分)- 2021 天梯赛
    L2-2 病毒溯源 (25 分)
    快速幂
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/8671841.html
Copyright © 2020-2023  润新知