大体题意:
有n 个体育馆每个体育馆里有 不同的精灵同样数字的精灵进化的结果是一样的不同数字进化的结果一定不同有多少个不同的进化方法使得每个体育馆进化后 和原来一样?
思路:
两个精灵可以互相进化的话,那么它们两个在所有的体育馆的数量和位置都必须一样。这样找出同类的所有数量后,求阶乘即可,因为它们内部随便排列都是合适的。
然后把所有的阶乘乘起来即可!
思路明确后,方法就很多了! 就随便写了。
例如:
我们可以把每种精灵的位置和数量 放在multiset里,最后把这个放在map里,最后枚举每个multiset的数量!
详细见代码:
#include <bits/stdc++.h>
#define fi first
#define se second
#define ps push_back
#define mr make_pair
using namespace std;
const int inf = 0x3f3f3f3f;
const int mod = 1e9+7;
typedef long long ll;
typedef unsigned long long LLU;
const double eps = 1e-10;
const double pi = acos(-1.0);
const int maxn = 1000000 + 10;
map<multiset<int>,int>mp;
multiset<int>g[maxn];
map<multiset<int>,int>::iterator it;
ll J(int x){
ll ans = 1LL;
for (int i = 1; i <= x; ++i){
ans = (ans % mod * i % mod) % mod;
}
return ans;
}
int main(){
int n, m;
scanf("%d %d",&n, &m);
for (int i = 0; i < n; ++i){
int k;
scanf("%d",&k);
for (int j = 0; j < k; ++j){
int v;
scanf("%d",&v);
g[v].insert(i);
}
}
for (int i = 1; i <= m; ++i){
mp[g[i]]++;
}
ll ans = 1LL;
for (it = mp.begin(); it != mp.end(); ++it){
int v = it->se;
ans = (ans%mod * J(v)%mod)%mod;
}
printf("%lld\n",ans);
return 0;
}