CF757 C hash
一种数字可以变成另一种数,要求每组中变换前后各种数字数量不变,问方案数
对现有每组中的每个数字构造出现在各个组情况的序列,如2 出现在第一组和第二组各一次那么就要加入组别的标号1,2,出现重复次仍要加入。
那么对所有数字构造完出现情况后,如果一种数字和另一种数字的出现情况是相同的,那么说明这两个数字是可以互相变换的。
所以我们用vector存出现情况,然后直接比较计算下贡献就行了。
#include <bits/stdc++.h> using namespace std; typedef long long LL; const LL mod = 1e9 + 7; int n, m; vector<LL>q[1000010]; LL fac[1000010]; bool vis[1000010]; void init() { fac[0] = fac[1] = 1; for(int i = 2; i <= 1000000; i++) { fac[i] = fac[i - 1] * (LL)i % mod; } } int main() { init(); while(cin >> n >> m) { int x, y; for(int i = 0; i < n; i++) { scanf("%d", &x); for(int j = 0; j < x; j++) { scanf("%d", &y); q[y].push_back(i); } } LL ans = 1; int cnt = 1; /*for(int i = 1; i <= m; i++)//TLE sort(q[i].begin(), q[i].end());*/ /*for(int i = 1; i <= m; i++) {//TLE if(vis[i]) continue; for(int j = i + 1; j <= m; j++) if(q[i] == q[j] && !vis[j]) cnt++, vis[j] = 1; ans = (ans * fac[cnt] % mod + mod) % mod; cnt = 1; }*/ sort(q + 1, q + 1 + m); for(int i = 2; i <= m; i++) { if(q[i] == q[i - 1]) cnt++; else ans = (ans * fac[cnt] % mod + mod) % mod, cnt = 1; } ans = (ans * fac[cnt] % mod + mod) % mod; printf("%lld\n", ans); } }