当前位置: 代码迷 >> 综合 >> codeforces 1466F. Euclid‘s nightmare
  详细解决方案

codeforces 1466F. Euclid‘s nightmare

热度:4   发布时间:2023-11-24 00:23:55.0

传送门

n个含两位1的向量,每个向量为1的维度互相连边,在不构成环的情况下,有2^n种可能(2^(n+1)个维度),在这个基础上只要加一条含一位1且该维度已出现过1,则可使|T|最大达到2^(n+1); 因此连边后每个连通块最多可包含一个只有一个1的向量并使答案翻倍, 所以可以把含一个1的向量看作连向m+1的边,然后用并查集找出所有边的条数即为答案

?#include <bits/stdc++.h>using namespace std;typedef long long int LL;const int N = 5e5 + 7;
const int MX = 1e9 + 7;int n, m;
int rep[N];int Find(int a) {if (rep[a] == a)return a;return rep[a] = Find(rep[a]);
}bool Union(int a, int b) {a = Find(a);b = Find(b);rep[a] = b;return a != b;
}int main() {scanf("%d %d", &n, &m);for (int i = 1; i <= m + 1; ++i)rep[i] = i;vector <int> ans;for (int i = 1; i <= n; ++i) {int k;scanf("%d", &k);int fa, fb = m + 1;scanf("%d", &fa);if (k > 1)scanf("%d", &fb);if (Union(fa, fb))ans.push_back(i);}int res = 1;for (int i = 0; i < (int)ans.size(); ++i)res = (res + res) % MX;printf("%d %d\n", res, (int)ans.size());for (auto v : ans)printf("%d ", v);puts("");return 0;
}