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;
}