首页 > 代码库 > P4700 算

P4700 算

P4700 算
时间: 1000ms / 空间: 125829120KiB / Java类名: Main

背景

zhx和他的妹子出去玩。

描述

技术分享

请在此填写题目描述

输入格式

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

输出格式

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

【样例输入】

3 3

【样例输出】

56

备注

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

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

题解:

等比数列:{a,aq1,aq2,aq3,aq4,aq5...aqn,...}

     前m项的前缀和:s=a(1-qm)/(1-m);

费马小定理:若p为质数,ap-1%p=1

逆元:若ax%p=1(p为质数),则a,x互为逆元

则ans=sigma(1,n)q(1-qm)/(1-m)

由于同余定理不支持除法,逆元处理:

  ans=sigma(1,n)q(1-qm)/(1-q)mod-2

考虑到负数问题

  ans=sigma(1,n)q(qm-1)/(q-1)mod-2

最终

  ans=sigma(1,n)q(qm-1)/(q-1)mod-2

代码:

#include<cstdio>#include<iostream>#define ll long longusing namespace std;const ll mod=1e9+7;ll n,m;inline ll fpow(ll a,ll p){    ll res=1;    for(;p;p>>=1,a=a*a%mod) if(p&1) res=res*a%mod;    return res%mod;}inline void solve(){    ll ans=n;    for(ll i=2,tmp,s;i<=n;i++){        /*自己推的*/         //tmp=fpow(i,m+1);        //s=((tmp-1+mod)%mod)*fpow(i-1,mod-2)%mod;        //ans=(ans+s-1+mod)%mod;        /*学哥讲的等比数列*/         tmp=i*(fpow(i,m)-1)%mod;        s=fpow((i-1),mod-2);        tans=(ans+tmp*s%mod)%mod;    }//应该是都对     cout<<ans%mod;}int main(){    ios::sync_with_stdio(false);    cin>>n>>m;    solve();    return 0;}

 

P4700 算