6038 Function

版权声明:本文为博主原创文章,未经博主允许不得转载。 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 n1 and a permutation b from 0 to m1.

Define that the domain of function f is the set of integers from 0 to n1, and the range of it is the set of integers from 0 to m1.

Please calculate the quantity of different functions f satisfying that f(i)=bf(ai) for each i from 0 to n1.

Two functions are different if and only if there exists at least one integer from 0 to n1 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. (1n100000,1m100000)

The second line contains n numbers, ranged from 0 to n1, the i-th number of which represents ai1.

The third line contains m numbers, ranged from 0 to m1, the i-th number of which represents bi1.

It is guaranteed that n106, m106.
 

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);

    }
}


猜你喜欢

转载自blog.csdn.net/Puppettt/article/details/76176781
今日推荐