• bzoj 3569: DZY Loves Chinese II


    Description

    神校XJ之学霸兮,Dzy皇考曰JC。
    摄提贞于孟陬兮,惟庚寅Dzy以降。
    纷Dzy既有此内美兮,又重之以修能。
    遂降临于OI界,欲以神力而凌♂辱众生。

    今Dzy有一魞歄图,其上有N座祭坛,又有M条膴蠁边。
    时而Dzy狂WA而怒发冲冠,神力外溢,遂有K条膴蠁边灰飞烟灭。
    而后俟其日A50题则又令其复原。(可视为立即复原)
    然若有祭坛无法相互到达,Dzy之神力便会大减,于是欲知其是否连通。

    题目大意:给定一张图,每次询问去掉几条边之后图是否连通

    Solution

    先做一棵生成树,然后给每一条非树边随机一个权值
    再把每一条树边的权值设为所有跨过这条边的非树边的权值的异或和

    如果存在不连通的情况一定是:跨过这条树边的所有非树边和这条边都被去掉了
    也就是存在一个子集的权值异或和为 (0)

    每一次用线性基判断一下就好了

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N=5e5+10;
    int n,m,fa[N],head[N],nxt[N*2],to[N*2],num=0,dep[N];bool v[N];
    ll x0=914241,mod=1e15,w[N],b[65];int p[20];
    inline ll seed(){return x0=(x0*41+19260817)%mod;}
    struct data{int x,y;ll w;}e[N];
    inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
    inline void link(int x,int y){nxt[++num]=head[x];to[num]=y;head[x]=num;}
    inline void dfs(int x,int last){
    	for(int u,i=head[x];i;i=nxt[i]){
    		if((u=to[i])==last)continue;
    		fa[u]=x;dep[u]=dep[x]+1;dfs(u,x);
    	}
    }
    inline void dfs1(int x){
    	for(int u,i=head[x];i;i=nxt[i]){
    		if((u=to[i])==fa[x])continue;
    		w[x]^=w[u];dfs1(u);
    	}
    }
    inline bool ins(ll x){
    	for(int i=60;i>=0;i--){
    		if(!(x>>i&1))continue;
    		if(!b[i]){b[i]=x;return true;}
    		else x^=b[i];
    		if(!x)return false;
    	}
    	return false;
    }
    int main(){
      freopen("pp.in","r",stdin);
      freopen("pp.out","w",stdout);
      srand(19260859);
      int x,y,Q,k,cnt=0;
      cin>>n>>m;
      for(int i=1;i<=n;i++)fa[i]=i;
      for(int i=1;i<=m;i++){
    	  scanf("%d%d",&x,&y);e[i]=(data){x,y};
    	  if(find(x)==find(y)){e[i].w=seed();continue;}
    	  fa[find(y)]=find(x);link(x,y);link(y,x);v[i]=1;
      }
      dfs(1,1);
      for(int i=1;i<=m;i++){
    	  if(dep[e[i].x]<dep[e[i].y])swap(e[i].x,e[i].y);
    	  if(v[i])continue;
    	  w[e[i].x]^=e[i].w;w[e[i].y]^=e[i].w;
      }
      dfs1(1);
      for(int i=1;i<=m;i++)if(v[i])e[i].w=w[e[i].x];
      cin>>Q;
      while(Q--){
    	  bool flag=1;
    	  scanf("%d",&k);
    	  for(int i=1;i<=k;i++)scanf("%d",&p[i]),p[i]^=cnt;
    	  for(int i=1;i<=k;i++)
    		  if(!ins(e[p[i]].w)){flag=0;break;}
    	  if(flag)puts("Connected"),cnt++;else puts("Disconnected");
    	  memset(b,0,sizeof(b));
      }
      return 0;
    }
    
    
  • 相关阅读:
    小批量随机梯度下降
    查询文档
    自动求梯度
    数据操作
    Hadoop 入门
    Matplotlib 二维图像绘制方法
    Pandas 数据处理基础
    NumPy 数值计算基础课程
    关于 Shell 脚本
    语法分析
  • 原文地址:https://www.cnblogs.com/Yuzao/p/8721423.html
Copyright © 2020-2023  润新知