數論 A - 夢 -----acdream ACdream原創羣賽(12)のBUAA選拔賽

題解By  kuangbin:

直接數學公式搞。

n個非負整數的和爲m的解個數爲C(n+m-1,n-1)

如果其中一個位置選擇了i, 那麼其餘的就是C(n-1 + m-i – 1, n-2), 這就是這個位置i出現次數,  然後位置有n個,再乘以n.

根據歐拉定理,指數對 1e9+6取模。

弱成狗。。。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<vector>
#include<iostream>
#include<string>
#include<queue>
#include<map>
#include<algorithm>
#include<math.h>
using namespace std;
//#define ull unsigned long long
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
#define eps 1e-7

ll c[2010][2010];
ll mod=1e9+6;
ll Mod=1e9+7;
ll C(ll n,ll k)    
{    
    if(c[n][k]!=-1) return c[n][k];    
    if(k==1) return c[n][k]=n;    
    if(k==0) return c[n][k]=1;    
    if(n==k) return c[n][k]=1;    
    if(k > (n>>1)) return c[n][k]=C(n,n-k);    
    return c[n][k]=(C(n-1,k-1)+C(n-1,k))%mod;    
}  
ll quickpow(ll m,ll n,ll k)  
{  
    ll b =1;  
    while (n >0)  
    {  
        if (n &1)  
            b = (b*m)%k;  
        n = n >>1 ;  
        m = (m*m)%k;  
    }  
    return b;  
}  

int main()
{
	int n,m,i,j,k;
	int t;
	scanf("%d",&t);
	memset(c,-1,sizeof(c));
	while(t--)
	{
		scanf("%d%d",&n,&m);
		if(n==1)
		{
			printf("%d\n",m);
			continue;
		}
		ll ans=1;
		for(i=2;i<=m;i++)
		{
			ans=(ans*quickpow((ll)i,C(n-2+m-i,m-i)*n,Mod))%Mod;
		}
		cout<<ans<<endl;
	}
}


發佈了212 篇原創文章 · 獲贊 3 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章