2017 Multi-University Training Contest - Team 1(hdu 6038 Function)

Function

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


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
 

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf = 1e9;
const int mod = 1e9+7;
	int book[111111];
		int ans[111111];
		int ans2[111111];

ll quick_pow(ll a,ll b){
	ll ans = 1;
	while(b){
		if(b&1) ans = (ans*a) % mod;
		b >>= 1;
		a = (a*a) % mod;
	}
	return ans;
}
int main(){
	std::ios::sync_with_stdio(false);
	int n,m;
	int caset = 0;
	while(cin>>n>>m){
		int ansc[111111] = {0};
		int cnt = 0;
		for(int i=0; i<n; i++)
			cin>>book[i];
		int mapp[111111] = {0};
		for(int i=0; i<n; i++)
			if(!mapp[i]){
				int count = 0;
				int tmp = i;
				do{
					mapp[tmp] = 1;
					tmp = book[tmp];
					count++;
				}while(tmp != i);
				int flag = 0;
				for(int j=0; j<cnt; j++){
					if(ans[j] == count)
						ansc[j]++,flag = 1;
				}
				if(!flag){
					ans[cnt++] = count;
					ansc[cnt-1]++;
				}
			}
			
		int ans2c[111111] = {0};
		int cnt2 = 0;
		for(int i=0; i<m; i++)
			cin>>book[i];
		memset(mapp, 0, sizeof(mapp));
		for(int i=0; i<m; i++)
			if(!mapp[i]){
				int count = 0;
				int tmp = i;
				do{
					mapp[tmp] = 1;
					tmp = book[tmp];
					count++;
				}while(tmp != i);
				int flag = 0;
				for(int j=0; j<cnt2; j++){
					if(ans2[j] == count)
						ans2c[j]++,flag = 1;
				}
				if(!flag){
					ans2[cnt2++] = count;
					ans2c[cnt2-1]++;
				}
			}
		
		ll anss = 1;
		for(int i=0; i<cnt; i++){ 
			ll tmp = 0;
			for(int j=0; j<cnt2; j++)
				if(ans[i]%ans2[j] == 0) tmp += ans2c[j]*ans2[j] % mod; 
			anss =( anss * quick_pow(tmp, ansc[i]) ) %mod;
		}
		cout<<"Case #"<<++caset<<": ";
		cout<<anss<<endl;
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值