题目地址
题意:给你一个a序列,代表0到n-1的排列;一个b序列代表0到m-1的排列。问你可以找出多少种函数关系,满足f(i)=b[f(a[i])];
官方题解:QAQ
代码:
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<vector>
#include<queue>
#include<set>
#include<algorithm>
#include<map>
using namespace std;
typedef long long int ll;
typedef pair<int,int>pa;
const int N=1e5+10;
const int mod=1e9+7;
const ll INF=1e18;
const int inf=1e4;
int read()
{
int x=0;
char ch = getchar();
while('0'>ch||ch>'9')ch=getchar();
while('0'<=ch&&ch<='9')
{
x=(x<<3)+(x<<1)+ch-'0';
ch=getchar();
}
return x;
}
/***********************************************************/
int n,m;
ll a[N],b[N],numa[N],numb[N];
int main()
{
int cas=0;
while(~scanf("%d%d",&n,&m))
{
memset(numb,0,sizeof(numb));
for(int i=0; i<n; i++)
scanf("%lld",&a[i]);
int cnt=0;
for(int i=0; i<n; i++)
{
ll tot=0;
int k=i;
while(a[k]!=-1)
{
tot++;
int t=k;
k=a[k];
a[t]=-1;
}
if(tot) numa[++cnt]=tot;
}
for(int i=0; i<m; i++) scanf("%lld",&b[i]);
for(int i=0; i<m; i++)
{
ll tot=0;
int k=i;
while(b[k]!=-1)
{
tot++;
int t=k;
k=b[k];
b[t]=-1;
}
if(tot) numb[tot]++;
}
ll ans=1;
for(int i=1; i<=cnt; i++)
{
ll ansl=0;
for(int j=1; j*j<=numa[i]; j++)
{
if(numa[i]%j==0)
{
if(j*j==numa[i])
ansl+=numb[j]*j;
else
ansl+=numb[j]*j+numb[numa[i]/j]*numa[i]/j;
}
}
ans=(ans*ansl)%mod;
}
printf("Case #%d: %lld\n", ++cas, ans);
}
}