• BZOJ 3569 DZY Loves Chinese II ——线性基


    【题目分析】

        腊鸡题目卡题面。

        大概的意思就是给一张无向图,每次删掉其中一些边,问是否联通。

        首先想到的是Bitset,可以做到n^2/64。显然过不了。

        然而这是lyd在给我们讲线性基的时候的一道题目。↓

        首先构建dfs树。

        发现图不联通的时候,当且仅当删去了树边和所有覆盖它的非树边。

        所以对于每一条非树边随机一个权值,然后每条树边为所有覆盖它的非树边的权值的异或。

        每次判断是否线性无关即可。

        神题!

    【代码】

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    
    #include <set>
    #include <map>
    #include <string>
    #include <algorithm>
    #include <vector>
    #include <iostream>
    #include <queue>
    
    using namespace std;
    
    #define maxn 100005
    #define maxm 1000005
    #define mxle 65
    #define ll long long 
    #define F(i,j,k) for (int i=j;i<=k;++i)
    #define D(i,j,k) for (int i=j;i>=k;--i)
    #define inf (0x3f3f3f3f)
    
    void Finout()
    {
        #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        #endif
    }
    
    int Getint()
    {
        int x=0,f=1; char ch=getchar();
        while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();}
        while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    
    vector <int> v[maxn]; 
    int h[maxm],fr[maxm],to[maxm],ne[maxm],en=0,f[maxn],tag[maxm];
    int w[maxm],b[maxm];
    int vis[maxm];
    
    void add(int a,int b)
    {
    	fr[en]=a; to[en]=b; ne[en]=h[a]; h[a]=en++;
    	fr[en]=b; to[en]=a; ne[en]=h[b]; h[b]=en++;
    }
    
    void dfs1(int o,int fa)
    {
    	vis[o]=1;
    	for (int i=h[o];i>=0;i=ne[i])
    	{
    		if (!vis[to[i]]) dfs1(to[i],o);
    		else if (!w[i]&&to[i]!=fa)
    		{
    			w[i]=w[i^1]=rand()*711;
    			b[o]^=w[i]; b[to[i]]^=w[i];
    		}
    	}
    }
    
    int n,m;
    
    void dfs2(int o)
    {
    	vis[o]=1;
    	for (int i=h[o];i>=0;i=ne[i])
    	{
    		if (!vis[to[i]])
    		{
    			dfs2(to[i]);
    			w[i]=w[i^1]=b[to[i]];
    			b[o]^=b[to[i]];
    		}
    	}
    }
    
    struct Base{
    	int lb[mxle];
    	bool add(int x)
    	{
    		D(i,30,0)
    		{
    			if ((x>>i)&1)
    			{
    				if (!lb[i]) {lb[i]=x;return false;}
    				else x^=lb[i];
    			}
    		}
    		return true;
    	}
    	void init(int x){memset(lb,0,sizeof lb);add(x);}
    }bas;
    
    int q,x,y;
    
    int main()
    {
    	memset(h,-1,sizeof h);
    	srand(20000416);
    	Finout();
    	n=Getint();m=Getint();
    	F(i,1,m) add(Getint(),Getint());
    	dfs1(1,0);
    	memset(vis,0,sizeof vis);
    	dfs2(1);
    	int ans=0,flag=0;
    	q=Getint();
    	F(i,1,q)
    	{
    		flag=0;
    		x=Getint(); bas.init(0);
    		F(i,1,x)
    		{
    			y=Getint(); y^=ans;
    			if (bas.add(w[2*y-1])) flag=1;
    		}
    		flag^=1;
    		if (flag) printf("Connected
    ");
    		else printf("Disconnected
    ");
    		ans+=flag;
    	}
    }
    

      

  • 相关阅读:
    模块(相当于Java里的包)
    if_else_while_for
    用户交互
    Python入门
    BigInteger类及方法应用
    selenium+java破解极验滑动验证码的示例代码
    Postman 使用详解
    Postman用法简介
    伟大架构师的秘密【转载】
    深入理解HTTP协议(转)
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6352111.html
Copyright © 2020-2023  润新知