牛客网-小白月赛6-J-洋灰三角

题目链接https://www.nowcoder.com/acm/contest/136/J

这题我还是不找规律了,老老实实推吧,传说找规律也可以,我还是算了

递推式:f(n)=k*f(n-1)+p

是的,你没有看错,这玩意是什么???是高中的数列求和啊,什么你没看出来,这玩意外号——一阶线性递推

等式两边同时加p/k-1   f(n)+p/(k-1) = k(f(n-1)+p/k-1);不信你可以推一下试试

那么f(n)可以通过等比数列求出f(n)=p/(k-1)*(k^(n-1))-p/(n-1);

再用分组求和那么前n项和公式为T(n)=(k^n-1)/(k-1)+p*(k^n-1)/(k-1)^2-p*n/(k-1)=(1+p/(k-1))*(k^n-1)/(k-1)-p*n/(k-1)

注意当n==1时T(n)=p*n*(n-1)/2+n;

有分数。求一下(k-1) % 1e9+7的逆元inv=pow(k-1,mod-2);

 

#include<iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
#define ll long long
using namespace std;;
const ll mod = 1e9+7;
ll pow(ll a,ll b)
{
    ll ans = 1;
    while(b)
    {
        if (b&1)
        {
            ans = ans*a%mod;
        }
        a = a*a%mod;
        b/=2;
    }
    return ans;
}
int main()
{
    ios::sync_with_stdio(0);
    ll n,k,p;
    ll ans=0;
    while(~scanf("%lld%lld%lld",&n,&k,&p))
    {
        if (k==1)
        {
             ans=(n*(n-1)%mod/2*p+n)%mod;
             printf("%lld\n",ans);
        }
        else
        {
            ll inv=pow(k-1,mod-2);
            ans=(1+p*inv%mod)%mod*((pow(k,n)-1+mod)%mod)%mod*inv%mod;
            ans=(ans-p*inv%mod*n%mod+mod)%mod;
            printf("%lld\n",ans);
        }
    }
    return 0;
}

 

posted @ 2018-08-19 19:30  bluefly-hrbust  阅读(192)  评论(0编辑  收藏  举报