Codeforces 757 C Felicity is Coming! 思维+STL

来源:互联网 发布:淘宝店铺关注排名 编辑:程序博客网 时间:2024/06/07 06:41

点击打开链接

题意:变换是一个排列f,f[i]为把i变为f[i],(i<=1e6)
有n(n<=1e5)个gym,要求种类经过f变换后:每个gym中每个种类个数:变化前和变换后相等,问有多少种合理变换f?


容易发现:若x经过变换后为y 则每个gym中x个数是等于y的个数(不好算直接统计出相等的种类).->x所在的gym集合等于y所在的gym集合 (vector[i] 种类i的的gym集合 sort后即可比较)
//若把能相互变换的放入一个数据结构中,则该块方法数为S!(S为该块的个数),最后每块方法数相乘即可 

#include <bits/stdc++.h>using namespace std;typedef long long ll;const ll mod=1e9+7;const int N=1e6+20;vector<int> a[N];//a[i]种类i的gym集合 int main(){int n,m;while(cin>>n>>m){for(int i=1;i<=n;i++){int num;scanf("%d",&num);while(num){int x;scanf("%d",&x);a[x].push_back(i);//num--;}}sort(a+1,a+1+m);//为了比较种类所在集合是否相等 ll t=1,ans=1;for(int i=2;i<=m;i++){if(a[i]==a[i-1]){t++;ans=(ans*t)%mod;}elset=1;}cout<<ans<<endl;for(int i=1;i<=n;i++)a[i].clear();}return 0;}




0 0