zoukankan      html  css  js  c++  java
  • 【BZOJ3563/BZOJ3569】DZY Loves Chinese I/II(随机化,线性基)

    【BZOJ3563/BZOJ3569】DZY Loves Chinese I/II(随机化,线性基)

    题面

    搞笑版本
    正经版本

    题面请自行观赏
    注意细节。

    题解

    搞笑版本真的是用来搞笑的
    所以我们来讲正经代码
    首先随便找一棵生成树出来
    于是,我们就得到了一棵树+若干边的东西
    如果删掉了若干边使得图不再联通,
    证明这条边,以及覆盖了这条边的那些边都被断开了。
    于是,我们给所有不再生成树上的边全部随机一个权值
    然后树上的边的权值为覆盖了它的所有边的权值异或和
    考虑如何查询,如果这一系列边都被断开,导致图不连通
    那么,证明可以从断开的边中选出一个非空子集,
    使得他们的异或和为(0)
    线性基实现即可

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define ll long long
    #define RG register
    #define MAX 111111
    #define MAXL 555555
    inline int read()
    {
        RG int x=0,t=1;RG char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-')t=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
        return x*t;
    }
    struct Line{int v,next,i;}e[MAX<<1];
    int h[MAX],cnt=1;
    inline void Add(int u,int v,int i){e[cnt]=(Line){v,h[u],i};h[u]=cnt++;}
    int f[MAX],V[MAXL],val[MAX];;
    int getf(int x){return x==f[x]?x:f[x]=getf(f[x]);}
    void dfs(int u,int ff)
    {
    	for(int i=h[u];i;i=e[i].next)
    		if(e[i].v!=ff)
    			dfs(e[i].v,u),V[e[i].i]^=val[e[i].v],val[u]^=val[e[i].v];
    }
    struct xxj
    {
    	int p[31];
    	void insert(int x)
    	{
    		for(int i=30;~i;--i)
    			if(x&(1<<i))
    			{
    				if(!p[i]){p[i]=x;break;}
    				x^=p[i];
    			}
    	}
    	bool Query(int x)
    	{
    		for(int i=30;~i;--i)
    			if(x&(1<<i))x^=p[i];
    		return x;
    	}
    	void init(){memset(p,0,sizeof(p));}
    }G;
    int n,m;
    int main()
    {
    	srand(5550555);
    	n=read();m=read();
    	for(int i=1;i<=n;++i)f[i]=i;
    	for(int i=1;i<=m;++i)
    	{
    		int u=read(),v=read();
    		if(getf(u)!=getf(v))
    			Add(u,v,i),Add(v,u,i),f[getf(u)]=getf(v);
    		else V[i]=rand()%(1<<30)+1,val[u]^=V[i],val[v]^=V[i];
    	}
    	dfs(1,0);
    	int ans=0,Q=read();
    	while(Q--)
    	{
    		int K=read();G.init();
    		bool fl=true;
    		while(K--)
    		{
    			int x=read()^ans;
    			if(G.Query(V[x]))G.insert(V[x]);
    			else fl=false;
    		}
    		fl?puts("Connected"):puts("Disconnected");
    		ans+=fl;
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    有一天,我们能这样相爱吗?
    端午节来源六说
    一个ini类代替缓存使用
    创意生活可爱香皂
    漂亮的韩国发饰
    Oracle中PL/SQL单行函数和组函数详解
    真正爱你的女人是这样的
    执子之手,与子偕老。你同意么?
    男人如茶
    Oracle SQL 內置函數大全
  • 原文地址:https://www.cnblogs.com/cjyyb/p/8724200.html
Copyright © 2011-2022 走看看