hdu 6038 Function

Function

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 1025    Accepted Submission(s): 457

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 #xy" 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
 
Recommend
liuyiding   |   We have carefully selected several similar problems for you:  6044 6043 6042 6041 6040 

 

题意:
给出两个序列,一个是0~n-1的排列a,另一个是0~m-1的排列b,现在求满足的f的个数。

 

思路:

找到a序列中的循环节个数,并且记录每个循环节中有多少因子,b序列同理

如果a中的某个循环节里面因子的个数能整除 b中某个循环节的因子个数,那就加上b的这个循环节因子的个数

最后乘起来就是结果,

然而一脸懵逼,传说中的高等线代。。。。。

#include <iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<bits/stdc++.h>

using namespace std;
const long long mod=1e9+7;
int n,m;
int a[1000005],b[1000005],a1[1000005],b1[1000005];
bool vis[1000005];
int acir,bcir;
int main()
{
    int cas=0;
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=0;i<n;i++) scanf("%d",&a[i]);
        for(int i=0;i<m;i++) scanf("%d",&b[i]);
        memset(vis,0,sizeof(vis));
        acir=0;
        for(int i=0;i<n;i++)
        {
            if (vis[i]) continue;
            int k=i;
            acir++; a1[acir]=0;
            while(!vis[k])
            {
                vis[k]=1;
                a1[acir]++;
                k=a[k];
            }
        }
        bcir=0;
        memset(vis,0,sizeof(vis));
        for(int i=0;i<m;i++)
        {
            if (vis[i]) continue;
            int k=i;
            bcir++; b1[bcir]=0;
            while(!vis[k])
            {
                vis[k]=1;
                b1[bcir]++;
                k=b[k];
            }
        }
       long long ans=1;
       for(int i=1;i<=acir;i++)
       {
           long long tmp=0;
           for(int j=1;j<=bcir;j++)
               if (a1[i]%b1[j]==0) tmp+=b1[j];
           ans=ans*tmp%mod;
       }
       printf("Case #%d: %lld\n",++cas,ans%mod);
    }
    return 0;
}

 

posted on 2017-07-26 17:28  Yxter  阅读(121)  评论(0编辑  收藏  举报

导航