本文主要是介绍【HDU】5793 A Boring Question,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
A Boring Question
题目链接
- A Boring Question
题目大意
要你求如下式子的值
∑0≤k1,k2...km≤n∏1≤j<m(kj+1kj)mod1000000007
题解
这个题只是看上去吓人而已…
比赛的时候大部分都是找规律过的,后来看官方题解才茅塞顿开。
首先可以分析出来:这个和要是不为0,序列k必须非减,所以我们考虑非减的情况就行了。
接下来开始化简:
∵序列非减∴∑0≤k1,k2...km≤n∏1≤j<m(kj+1kj)=∑kmn∑km−1km...∑k1=0k2(k2k1)(k3k2)...(kmkm−1)
注意到后面的积可以分别提到和式的前面。
∑kmn∑km−1km(kmkm−1)∑km−2km−1(km−1km−2)...∑k1=0k2(k2k1)
这时,我们发现最里面的一项就是 2k2 ,所以有:
∑kmn∑km−1km(kmkm−1)∑km−2km−1(km−1km−2)...∑k2k3(k3k2)⋅2k2
这时我们又发现此时的最后一项又可以由二项式展开来化简:
∑k2k3(k3k2)⋅2k2=(2+1)k3=3k3
这样一直进行化简,最后可以得到:
∑kmn∑km−1km(kmkm−1)⋅(m−1)km−1=∑kmnmkm
这样在最后就是一个等比数列求和了。
最终结果:
ans=mn+1−1m−1
代码
#include <iostream>
#include <cstring>
#include <cstdio>
#define mod 1000000007
#define LL long longusing namespace std;int T;
LL n,m;LL pow_mod(LL a,LL b,LL c)
{LL ans=1;while (b){if (b&1) ans=(ans*a)%c;b>>=1;a=(a*a)%c;}return ans;
}int main()
{scanf("%d",&T);while (T--){scanf("%lld%lld",&n,&m);LL ans=(pow_mod(m,n+1,mod)-1)*pow_mod(m-1,mod-2,mod);ans=(ans+mod)%mod;printf("%I64d\n",ans);}return 0;
}
这篇关于【HDU】5793 A Boring Question的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!