版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Puppettt/article/details/76176781
Function
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1300 Accepted Submission(s): 599
Problem Description
You are given a permutation
a from
0 to
n−1 and a permutation
b from
0 to
m−1.
Define that the domain of function f is the set of integers from 0 to n−1, and the range of it is the set of integers from 0 to m−1.
Please calculate the quantity of different functions f satisfying that f(i)=bf(ai) for each i from 0 to n−1.
Two functions are different if and only if there exists at least one integer from 0 to n−1 mapped into different integers in these two functions.
The answer may be too large, so please output it in modulo 109+7.
Define that the domain of function f is the set of integers from 0 to n−1, and the range of it is the set of integers from 0 to m−1.
Please calculate the quantity of different functions f satisfying that f(i)=bf(ai) for each i from 0 to n−1.
Two functions are different if and only if there exists at least one integer from 0 to n−1 mapped into different integers in these two functions.
The answer may be too large, so please output it in modulo 109+7.
Input
The input contains multiple test cases.
For each case:
The first line contains two numbers n, m. (1≤n≤100000,1≤m≤100000)
The second line contains n numbers, ranged from 0 to n−1, the i-th number of which represents ai−1.
The third line contains m numbers, ranged from 0 to m−1, the i-th number of which represents bi−1.
It is guaranteed that ∑n≤106, ∑m≤106.
For each case:
The first line contains two numbers n, m. (1≤n≤100000,1≤m≤100000)
The second line contains n numbers, ranged from 0 to n−1, the i-th number of which represents ai−1.
The third line contains m numbers, ranged from 0 to m−1, the i-th number of which represents bi−1.
It is guaranteed that ∑n≤106, ∑m≤106.
Output
For each test case, output "
Case #x: y" in one line (without quotes), where
x indicates the case number starting from
1 and
y denotes the answer of corresponding case.
Sample Input
3 2 1 0 2 0 1 3 4 2 0 1 0 2 3 1
Sample Output
Case #1: 4 Case #2: 4
Source
2017 Multi-University Training Contest - Team 1
思路:
函数的映射。每个f(x)与ax关联关系链成环。必须有相应的b与a对应(一个a只能有一个b,一个b可以有多个a对应)。
先处理a和b有几个环 ,再 b组成(每个)a环的种类数。 一个有k个元素的b环有k种可能有num[k]=x个有k个元素的b 环就是有 num[k]*k种可能。a环元素有k个元素同时可以由k的因子成环(如果k为4 ,k可以由4个元素的、2个元素的、1个元素的环组成)所以对于一个a环可以由sum=num[x1]*x1+num[x2]*x2+num[x3]*x3…. (x1,x2,x3为k的因子)。 如果有t个有k个因子的a环 ans*=sum1^t1;所有a环答案相乘就是最后的答案。
AC:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
typedef long long LL;
using namespace std;
int vis[100100]={0};int mem[100100]={0},VIS[100100]={0};
int cira[100100]={0},cirb[100100]={0};
int main()
{
int n,m;
int v=1;
while(scanf("%d%d",&n,&m)!=EOF)
{
int a[100100]={0},b[100100]={0};
for(int i=0;i<n;i++)scanf("%d",&a[i]);
int s,next,num=1;
memset(VIS,0,sizeof(VIS));
memset(cira,0,sizeof(cira));
memset(cirb,0,sizeof(cirb));
memset(vis,0,sizeof(vis));
memset(mem,0,sizeof(mem));
///the circle of A
int d=0;
for(int i=0;i<n;i++)
{
s=i,next=a[i],num=1;
if(VIS[s]==1)continue;
VIS[s]=1;
//printf("s= %d \n",s);
while(next!= s)
{
VIS[next]=1;
next=a[next];
num++;
}
cira[num]++;
if(!vis[num])mem[d++]=num;
vis[num]=1;
}
//for(int i=0;i<10;i++)printf("ciara[%d]=%d ",i,cira[i]);
for(int i=0;i<m;i++)scanf("%d",&b[i]);
memset(VIS,0,sizeof(VIS));
///the circle of B
for(int i=0;i<m;i++)
{
s=i,next=b[i],num=1;
if(VIS[s]==1)continue;
VIS[s]=1;
//printf("s= %d \n",s);
while(next!= s)
{
VIS[next]=1;
next=b[next];
num++;
}
cirb[num]++;
}
//for(int i=0;i<10;i++)printf("ciarb[%d]=%d ",i,cirb[i]);
LL ans=1;
//cout<<"a:";
for(int i=0;i<d;i++)
{
int k=mem[i];
//printf("%d \n",k);
LL temp=0;
for(int j=1;j<=k;j++)
{
if(k%j==0)temp+=j*cirb[j];
}
//cout<<"temp:"<<temp<<endl;
LL T=1;
for(int j=1;j<=cira[k];j++)
T*=temp;
ans*=T;
}
//cout<<endl;
printf("Case #%d: %lld\n",v++,ans);
}
}