zoukankan      html  css  js  c++  java
  • BZOJ 3569: DZY Loves Chinese II(线性基)

    传送门

    解题思路

      首先构造出一个生成树,考虑不连接的情况。假设连通两点的非树边和树边都断掉后不连通,那么可以给所有的非树边随机一个互不相同的值,然后树边的权值为过他两端点的非树边权值的异或和,这个可以用一个类似树上差分的东西来实现。询问的时候把所有询问的边权加到线性基里,看是否某个数字能被线性表出。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<cstdlib>
    #include<ctime>
    #include<set>
    
    using namespace std;
    const int N=100005;
    const int M=500005;
    const int INF=(1<<30);
    
    inline int rd(){
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)) f=ch=='-'?0:1,ch=getchar();
    	while(isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
    	return f?x:-x;
    }
    
    int n,m,head[N],cnt,to[N<<1],nxt[N<<1],Q,b[35],F[N];
    int tag[N],tot,id[N<<1],ans;
    bool flag;
    set<int> S;
    
    struct Edge{
    	int u,v,w;
    }edge[M];
    
    inline void add(int bg,int ed,int Id){
    	to[++cnt]=ed,nxt[cnt]=head[bg],id[cnt]=Id,head[bg]=cnt;
    }
    
    int get(int x){
    	if(x==F[x]) return x;
    	return F[x]=get(F[x]);
    }
    
    void dfs(int x,int fa){
    	for(int i=head[x];i;i=nxt[i]){
    		int u=to[i]; if(u==fa) continue;
    		dfs(u,x);
    		edge[id[i]].w^=tag[u];
    		tag[x]^=tag[u];	
    	}
    }
    
    inline void init(){
    	memset(b,0,sizeof(b));
    	flag=false;
    }
    
    inline void Insert(int x){
    	for(int i=30;~i;i--)
    		if(x&(1<<i)){
    			if(!b[i]) {b[i]=x; return ;}
    			x^=b[i];
    		}
    	if(!x) flag=1;
    }
    
    int main(){
    	srand(time(0)); srand(rand()); srand(20020426);
    	n=rd(),m=rd();int x,y;
    	for(int i=1;i<=n;i++) F[i]=i;
    	for(int i=1;i<=m;i++)
    		edge[i].u=rd(),edge[i].v=rd();
    	for(int i=1;i<=m;i++){
    		x=get(edge[i].u); y=get(edge[i].v);
    		if(x==y) {
    			edge[i].w=rand()%INF;
    			while(S.find(edge[i].w)!=S.end()) edge[i].w=rand()%INF;
    			S.insert(edge[i].w);
    			tag[edge[i].u]^=edge[i].w; 
    			tag[edge[i].v]^=edge[i].w;
    			continue;
    		}
    		add(edge[i].u,edge[i].v,i); add(edge[i].v,edge[i].u,i);
    		F[x]=y; tot++;
    	}	
    	dfs(1,0); Q=rd();
    	while(Q--){
    		init();
    		for(x=rd();x;x--) y=(rd()^ans),Insert(edge[y].w);
    		if(flag) puts("Disconnected");
    		else puts("Connected"),ans++;
    	}
    	return 0;
    }	
    
  • 相关阅读:
    js点击弹出div层
    图片按比例缩小
    js标题文字向上滚动
    JS刷新当前页面
    图片缩放显示,不变形
    产品叠加搜索
    Oracle中DML基础知识
    Oracle中DDL的基础知识
    Sql多对多关系中外键的应用
    oracle 中sql语句的几个基本函数..
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/10280458.html
Copyright © 2011-2022 走看看