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\n",poww(n-cnt),n-cnt);
    for(int i=1;i<=n;++i)
        if(use[i]) printf("%d ",i);
}
复制代码

 

posted @   TRTTG  阅读(68)  评论(0编辑  收藏  举报
编辑推荐:
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
历史上的今天:
2018-10-19 致备战noip2018的勇士
2017-10-19 UVA 690 Pipeline Scheduling
2017-10-19 2017 国庆湖南 Day4
2017-10-19 2017 国庆湖南 Day5
2017-10-19 2017 国庆湖南 Day6
2017-10-19 2017国庆 清北学堂 北京综合强化班 Day1
点击右上角即可分享
微信分享提示