zoukankan      html  css  js  c++  java
  • 【HDU6038】Function-思维+组合数学

    测试地址:Function
    题目大意: 给出一个关于00n1n-1的置换aa,一个关于00m1m-1的置换bb,求有多少从00n1n-1映射到00m1m-1的映射ff,满足f(i)=bf(ai)f(i)=b_{f(a_i)}
    做法: 本题需要用到思维+组合数学。
    根据题目的要求,f(ai)f(a_i)可以通过置换bb成为f(i)f(i),所以我们对于置换aa画一个反向循环图(即,从点ii可以走到点aia_i,反向就是从点aia_i走到点ii),再对置换bb画一个循环图,在两张图中分别选出两个点x,yx,y,代表f(x)=yf(x)=y,那么可以发现,当xx走一步,yy也走一步,f(x)=yf(x)=y应该还是成立的。这也就说明,yybb中的循环长度,应该是xxaa中循环长度的因数,这样才能保证f(x)=yf(x)=y在走的过程中总是成立。而因为初始的yy又有len(y)len(y)种选择(len(y)len(y)yy所在循环的长度),因此我们找到了一种统计答案的方法:对一个aa中的环,在bb中找到所有环长为这个环长的因数的环,累加len(y)len(y)。直接统计因数的贡献比较麻烦,我们反过来考虑每个bb中的环,它对环长为len(y)len(y)的倍数的环有len(y)len(y)贡献,我们只需要一开始算出counticount_i,表示环长为iibb中的环的个数,就可以O(mlogm)O(mlog m)计算贡献了。那么对于aa中的每个环,可以计算出这个环的方案数,运用乘法原理把每个环的方案数乘起来就行了。
    我傻逼的地方:我又分不清楚nnmm了…这错误一次比一次觉得傻逼…
    以下是本人代码:

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll mod=1000000007;
    int n,m,a[100010],b[100010],tot;
    ll cnt[100010],tmp[100010];
    bool vis[100010];
    
    void find_loop(int *nxt,int v)
    {
    	while(!vis[v])
    	{
    		vis[v]=1;tot++;
    		v=nxt[v];
    	}
    }
    
    int main()
    {
    	int t=0;
    	while(scanf("%d%d",&n,&m)!=EOF)
    	{
    		for(int i=0;i<n;i++)
    			scanf("%d",&a[i]);
    		for(int i=0;i<m;i++)
    			scanf("%d",&b[i]);
    		
    		for(int i=0;i<=m;i++)
    			tmp[i]=vis[i]=0;
    		for(int i=0;i<m;i++)
    			if (!vis[i])
    			{
    				tot=0;
    				find_loop(b,i);
    				tmp[tot]++;
    			}
    		for(int i=1;i<=n;i++)
    			cnt[i]=0;
    		for(int i=1;i<=m;i++)
    			for(int j=1;i*j<=n;j++)
    				cnt[i*j]=(cnt[i*j]+tmp[i]*(ll)i)%mod;
    		
    		ll ans=1;
    		for(int i=0;i<n;i++)
    			vis[i]=0;
    		for(int i=0;i<n;i++)
    			if (!vis[i])
    			{
    				tot=0;
    				find_loop(a,i);
    				ans=ans*cnt[tot]%mod;
    			}
    		printf("Case #%d: %lld
    ",++t,ans);
    	}
    	
    	return 0; 
    }
    
  • 相关阅读:
    每天一道LeetCode--141.Linked List Cycle(链表环问题)
    每天一道LeetCode--119.Pascal's Triangle II(杨辉三角)
    每天一道LeetCode--118. Pascal's Triangle(杨辉三角)
    CF1277D Let's Play the Words?
    CF1281B Azamon Web Services
    CF1197D Yet Another Subarray Problem
    CF1237D Balanced Playlist
    CF1239A Ivan the Fool and the Probability Theory
    CF1223D Sequence Sorting
    CF1228D Complete Tripartite
  • 原文地址:https://www.cnblogs.com/Maxwei-wzj/p/9793250.html
Copyright © 2011-2022 走看看