等比数列求和+逆元——算

来源:互联网 发布:杜兰特新秀体测时数据 编辑:程序博客网 时间:2024/05/16 03:56

问题背景

zhx 帮他妹子做数学题。

 

问题描述

求: 


如N=3, M=3,这个值为1^1+1^2+1^3+2^1+2^2+2^3+3^1+3^2+3^3=56。


输入格式

仅一行,包含两个数N和M.  

 

输出格式

仅一行,包含所求的答案 mod 10^9 + 7 的值。


样例输入

3 3 


样例输出

56 


数据范围与规定 

对于50%的数据,所有1 ≤N,M ≤ 1000。 
对于100%的数据,所有1 ≤N,M≤ 50000。  


思路

用一个美丽的高一数学公式:等比数列求和公式




就可以把这个假·O(N*M)的题优化为真·O(N)算法

注意:因为所求答案是模意义下的 所以需要一个O(N)的线性推逆元算法


代码(C++)

#include <cstdio>#define ll long longusing namespace std;const ll mod=1000000007;ll N,M,i,j,ans,ny[50010]={1,1};ll ksm(ll num,ll sum);int main(){scanf("%lld%lld",&N,&M);for(i=2;i<=N;i++)ny[i]=(mod-mod/i)*ny[mod%i]%mod;ans+=M;for(i=2;i<=N;++i)ans=(ans+i*(ksm(i,M)-1)%mod*ny[i-1]%mod)%mod;printf("%lld",ans);return 0;}ll ksm(ll num,ll sum){if(sum==1)return num;ll k=ksm(num,sum/2);k=k*k%mod;if(sum%2==0)return k;elsereturn k*num%mod;}


原创粉丝点击