hdu 6050 Function 想法題

Function

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.

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 .

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

題目鏈接

題意:給你一個a數組和b數組,叫你構造f函數滿足所有的f(i)=bf(ai)

解題思路:對於a數組中的一個長度爲l的環,我們只需要找在b中長度爲 l的約數的環使得a數組中的數與b數組中的數一一對應就好,例如a={1,2,3,0},b={1,0},則我們可以讓a0->b1,a1->b0,a2->b1,a3->b0或者a0->b0,a1->b1,a2->b0,a3->b1,則這樣就是兩種情況,然後我們能得知,對於兩個對應的a,b環,f的種類其實就爲b環的長度,因此我們便可以直接得出ans=(b中與a環對應的環的長度的總和相乘)

#include<cstdio>
#include<cstring>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
ll n,m,a[100005],b[100005],mark[100005];
ll len;
ll s2[100005];
ll ans;
const ll mod=1000000007;
vector<ll>p[100005];
vector<ll>q;
void init(){
    for(ll i=1;i<=100000;i++){
        for(ll j=1;j*j<=i;j++){
            if(i%j==0&&j*j!=i){
                p[i].push_back(j);
                p[i].push_back(i/j);
            }
            else if(i%j==0&&j*j==i)    p[i].push_back(j);
        }
    }
}
int main(){
    init();
    ll cas=1;
    while(scanf("%lld%lld",&n,&m)!=EOF){
        q.clear();
        ans=1;
        memset(s2,0,sizeof(s2));
        for(ll i=0;i<n;i++)    scanf("%lld",&a[i]);
        for(ll i=0;i<m;i++)    scanf("%lld",&b[i]);
        memset(mark,0,sizeof(mark));
        for(ll i=0;i<n;i++){
            if(mark[i]==0){
                mark[i]=1;
                len=1;
                ll now=a[i];
                while(mark[now]==0){
                    mark[now]=++len;
                    now=a[now];
                }
                q.push_back(len);
            }
        }
        memset(mark,0,sizeof(mark));
        for(ll i=0;i<m;i++){
            if(mark[i]==0){
                mark[i]=1;
                len=1;
                ll now=b[i];
                while(mark[now]==0){
                    mark[now]=++len;
                    now=b[now];
                }
                s2[len]++;
            }
        }
        for(ll i=0;i<q.size();i++){
            ll sum=0;
            for(ll j=0;j<p[q[i]].size();j++){
                sum=(sum+s2[p[q[i]][j]]*p[q[i]][j])%mod;
            }
            ans=(ans*sum)%mod;
        }
        printf("Case #%lld: %lld\n",cas++,ans);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章