zoukankan      html  css  js  c++  java
  • 【BZOJ3569】DZY Loves Chinese II(线性基)

    点此看题面

    大致题意: 给定一个无向图,每次删去其中若干条边,询问连通性。(询问独立,强制在线)

    随机权值

    这应该是一道比较套路的题目。

    我们随便取一棵生成树,那么原先的边自然就分成了树边和非树边。

    考虑给每条非树边随机一个权值,并令每条树边的权值为所有覆盖它的边的权值异或和。

    则给定的边集如果存在一个子集,满足其中边权异或和为(0),就说明不连通(因为相当于把这条树边连接的两个连通块分开了)。

    而要求是否存在一个异或和为(0)的子集,显然只要用线性基记录即可。

    树边权值

    等等,我们该如何求出覆盖一条树边的非树边权值异或和呢?

    考虑对于一条非树边,我们把它连接的两个点的点权都异或上这条边的权值。

    则如果一条非树边连的两个点都在子树内,权值异或相抵消;如果都在子树外,不会造成影响。

    所以,我们只要求出一条树边子节点子树内点权异或和,能造成贡献的非树边所连接的两个点必然一个在子树内、一个在子树外,也就必然覆盖这条边。因此这就是该树边的权值了。

    代码

    #include<bits/stdc++.h>
    #define Tp template<typename Ty>
    #define Ts template<typename Ty,typename... Ar>
    #define Reg register
    #define RI Reg int
    #define Con const
    #define CI Con int&
    #define I inline
    #define W while
    #define N 100000
    #define M 500000
    #define add(p,x,y) (e[++ee].id=p,e[ee].nxt=lnk[x],e[lnk[x]=ee].to=y)
    #define ull unsigned long long
    using namespace std;
    int n,m,ee,lnk[N+5],f[N+5];struct edge {int id,to,nxt;}e[2*N+5];
    struct line {int x,y;ull v;}s[M+5];
    class FastIO
    {
    	private:
    		#define FS 100000
    		#define tc() (A==B&&(B=(A=FI)+fread(FI,1,FS,stdin),A==B)?EOF:*A++)
    		#define D isdigit(c=tc())
    		char c,*A,*B,FI[FS];
    	public:
    		I FastIO() {A=B=FI;}
    		Tp I void read(Ty& x) {x=0;W(!D);W(x=(x<<3)+(x<<1)+(c&15),D);}
    		Ts I void read(Ty& x,Ar&... y) {read(x),read(y...);}
    }F;
    class LinearBasis//线性基
    {
    	private:
    		int fg;ull v[65];
    	public:
    		I void Clear() {fg=0;for(RI i=64;~i;--i) v[i]=0;}
    		I void Ins(ull x)
    		{
    			for(RI i=64;~i;--i) if((x>>i)&1)
    				{if(!v[i]) return (void)(v[i]=x);x^=v[i];}fg=1;//fg记录是否有0
    		}
    		I int Qry() {return fg;}
    }B;
    ull v[N+5];I void dfs(CI x,CI lst=0)//遍历树
    {
    	for(RI i=lnk[x];i;i=e[i].nxt) e[i].to^lst&&
    		(dfs(e[i].to,x),v[x]^=(s[e[i].id].v=v[e[i].to]));//统计子树权值异或和
    }
    I int fa(CI x) {return f[x]?f[x]=fa(f[x]):x;}//并查集
    int main()
    {
    	RI i,x,y;for(F.read(n,m),i=1;i<=m;++i) F.read(s[i].x,s[i].y),
    		(x=fa(s[i].x))^(y=fa(s[i].y))?(f[y]=x,add(i,s[i].x,s[i].y),add(i,s[i].y,s[i].x))//树边连边
    		:(v[s[i].x]^=(s[i].v=1ull*rand()*rand()*rand()*rand()*rand()),v[s[i].y]^=s[i].v);//非树边随机权值,修改点权
    	RI Qt,k,cnt=0;dfs(1),F.read(Qt);W(Qt--)
    	{
    		for(B.Clear(),F.read(k),i=1;i<=k;++i) F.read(x),B.Ins(s[x^cnt].v);//插入线性基
    		puts(B.Qry()?"Disconnected":(++cnt,"Connected"));//判断输出
    	}return 0;
    }
    
  • 相关阅读:
    pycharm安装破解
    flask动态生成csv
    使用django开发restful接口
    python matplotlib显示中文和负数符号
    locust性能测试02—检查点
    locust性能测试01—初体验
    Mac中配置jmeter+grafana监控
    CF731E Funny Game
    CF197A Plate Game
    luoguP1823 [COI2007] Patrik 音乐会的等待
  • 原文地址:https://www.cnblogs.com/chenxiaoran666/p/BZOJ3569.html
Copyright © 2011-2022 走看看