#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
const ll N=1000000007;
ll pow_mod(ll a,ll n,ll m){ //快速幂运算
if(n==0) return 1;
ll x=pow_mod(a,n/2,m);
ll ans=x*x%m;
if(n%2==1) ans=ans*a%m;
return ans;
}
ll exgcd(ll a,ll b,ll &x,ll &y){
if(b==0){
x=1;y=0;return a;
}
ll ans=exgcd(b,a%b,x,y);
ll t=x;
x=y;
y=t-(a/b)*y;
return ans;
}
ll rev(ll b,ll n){ //求逆元
ll x=0,y=0;
ll g=exgcd(b,n,x,y);
return x;
}
int main(){
int t;
scanf("%d",&t);
ll n,m;
while(t--){
scanf("%lld %lld",&n,&m);
ll ans=0;
ans=((pow_mod(m,n+1,N)-1)*rev(m-1,N))%N;
printf("%lld\n",(ans+N)%N);
}
}
题意:用m个不大于n的数构成一个序列,对每个序列求组合数C(ki+1,ki)的乘积,并累乘该乘积;
我开始是人肉打表的……但是并没有找到规律,网上后来有出打表的代码,地址会贴在下面,如果打表多一点也许能找到规律吧QAQ;
打表后的规律是;
考虑到到题目的10^9,对于m^(n+1)我们需要用快速幂模板(提高效率)进行计算;
因为除法操作后还要进行取模,所以我们要用逆元(乘法再除法取模可能会除不尽)模板进行计算;
因为取模运算之后可能会爆掉变成负数,所以最好要(ans+N)%N;
打表代码参考:http://blog.csdn.net/angon823/article/details/52125711