题意:喜马拉雅山地区有有m种小精灵和n个道馆,每个道馆里面有g[i]个小精灵。这个地方存在一个训练营,能够进化小精灵,进化的条件限制是:f(x)=y当且仅当x在每个道馆中的数量等于y,求可以满足条件的进化方案数。
思路:根据题意来,如果能将所有的小精灵分成若干个集合x1,x2,...,xk,使得每个集合里面的小精灵在每个道馆中出现的次数都相同,那么ans=[x1]!*[x2]!*...*[xk]!([xi]表示xi集合中小精灵的数量)
PS:打的时候一直没有想通这点,只想到要排列,但是不知怎么排,看了别人的代码后才知道,利用vector分集合也是很强势,第一次看到,记笔记记笔记......
1 #include <iostream> 2 #include <queue> 3 #include <stack> 4 #include <cstdio> 5 #include <vector> 6 #include <map> 7 #include <set> 8 #include <bitset> 9 #include <algorithm> 10 #include <cmath> 11 #include <cstring> 12 #include <cstdlib> 13 #include <string> 14 #include <sstream> 15 #include <time.h> 16 #define x first 17 #define y second 18 #define pb push_back 19 #define mp make_pair 20 #define lson l,m,rt*2 21 #define rson m+1,r,rt*2+1 22 #define mt(A,B) memset(A,B,sizeof(A)) 23 #define mod 1000000007 24 using namespace std; 25 typedef long long LL; 26 const double PI = acos(-1); 27 const int N=1e6+10; 28 const int inf = 0x3f3f3f3f; 29 const LL INF=0x3f3f3f3f3f3f3f3fLL; 30 vector<LL> Q[N]; 31 int main() 32 { 33 #ifdef Local 34 freopen("data.txt","r",stdin); 35 #endif 36 LL n,m,k=1,ans=1; 37 cin>>n>>m; 38 for(int i=1;i<=n;i++) 39 { 40 LL g,x; 41 cin>>g; 42 while(g--) 43 { 44 cin>>x; 45 Q[x].pb(i); 46 } 47 } 48 sort(Q+1,Q+1+m);//这个排序很神奇 49 for(int i=2;i<=m;i++) 50 { 51 if(Q[i]==Q[i-1])//这个==也很神奇 52 { 53 k++; 54 ans=(ans*k)%mod; 55 } 56 else k=1; 57 } 58 cout<<ans<<endl; 59 #ifdef Local 60 cerr << "time: " << (LL) clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl; 61 #endif 62 }