1. 程式人生 > >CF757 C hash

CF757 C hash

clu 直接 我們 出現 def 重復 變換 ont printf

一種數字可以變成另一種數,要求每組中變換前後各種數字數量不變,問方案數

對現有每組中的每個數字構造出現在各個組情況的序列,如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);
	}
}

CF757 C hash