zoukankan      html  css  js  c++  java
  • CF1466 F. Euclid's nightmare

    Problem - F - Codeforces

    题意:

    有n个不一样的m维向量,每个维度要么是0,要么是1,而且至多有2个维度是1

    问这些向量取任意个在模2意义下相加,能得出多少种不同的向量

    并找到一个个数最少且字典序最小的小向量集,里面的向量按上述相加可以得出答案的所有向量

    加一个虚拟节点

    若向量在第x维和第y维是1,x和y之间连边

    若向量只在第x维是1,虚拟节点和x之间连边

    在连边过程中,如果加入一条边出现了环,那么这个向量是无效的

    因为环上的点每个点都会被累加2次,模2都是0

    按输入顺序一个向量一个向量的加就可以了

    #include<bits/stdc++.h>
    
    using namespace std;
    
    #define N 500003
    
    int fa[N];
    bool vis[N];
    bool use[N];
    
    const int mod=1e9+7;
    
    int find(int i) { return fa[i]==i ? i : fa[i]=find(fa[i]); } 
    
    int unionn(int x,int y)
    {
        int fx=find(x),fy=find(y);
        if(fx==fy) return 1;
        fa[fx]=fy;
        return 0;
    }
    
    int poww(int b)
    {
        int a=2,c=1;
        for(;b;a=1ll*a*a%mod,b>>=1)
            if(b&1) c=1ll*c*a%mod;
        return c;
    }
    
    int main()
    {
        int n,m,k,x,y;
        int cnt=0;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;++i) fa[i]=i;
        for(int i=1;i<=n;++i)
        {
            scanf("%d",&k);
            if(!k) continue;
            y=0;
            if(k==1) scanf("%d",&x);
            else if(k==2) scanf("%d%d",&x,&y);
            if(unionn(x,y)) ++cnt;
            else use[i]=true;
        }
        printf("%d %d
    ",poww(n-cnt),n-cnt);
        for(int i=1;i<=n;++i)
            if(use[i]) printf("%d ",i);
    }
    作者:xxy
    本文版权归作者和博客园共有,转载请用链接,请勿原文转载,Thanks♪(・ω・)ノ。
  • 相关阅读:
    [辛酸历程]在Mac中使用Python获取屏幕截图
    一个简单的验证码识别教程
    JavaScript的函数作用域
    函数声明和函数表达式
    数组 方法和属性
    递归
    闭包
    浏览器解析JavaScript原理
    JavaScript的数据类型2
    利用canvas画一个动态时钟
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/15426249.html
Copyright © 2011-2022 走看看