传送门
题意:
a
1
_1
1=1,
a
2
_2
2=a
1
_1
1*k+p,
a
3
_3
3=a
2
_2
2*k+p ,
a
n
_n
n=a
n
−
1
_{n-1}
n−1*k+p,
求S
n
_n
n。
思路:高中数学中推导S
n
_n
n的时候其实就是这么推到的。
左边=S
n
_n
n
右边=S
n
−
1
_{n-1}
n−1*k+(n-1)*p+1
整理得:
S
n
S_{n}
Sn=
(
a
n
(a_n
(an*k-(n-1)*p-1)/(k-1)
这样就只需要求出a
n
_n
n就可以解决啦。
所以,a
n
_n
n的话我们推一个简单的矩阵就可以轻松求出。
当然这道题还有其他的很多做法。
#include<bits/stdc++.h>
#define debug(a) cout << #a << " " << a << endl
#define LL long long
#define ull unsigned long long
#define PI acos(-1.0)
#define eps 1e-6
const int N=1e6+7;
const int mod=1e9+7;
using namespace std;
const int M=2;
struct mat
{
LL x[M][M];
};
mat Muti(mat a,mat b){
mat ans;
memset(ans.x,0,sizeof ans.x);
for(int i=0;i<M;i++)
for(int j=0;j<M;j++)
for(int k=0;k<M;k++){
ans.x[i][j]+=a.x[i][k]*b.x[k][j];
ans.x[i][j]%=mod;
}
return ans;
}
mat Powmat(mat a,LL b){
mat tmp;
memset(tmp.x,0,sizeof tmp.x);
for(int i=0;i<M;i++)
tmp.x[i][i]=1LL;
while(b){
if(b&1) tmp=Muti(tmp,a);
a=Muti(a,a);
b=b/2;
}
return tmp;
}
LL mypow(LL a,LL b)
{
LL ans=1;
while(b)
{
if(b&1) ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
int main()
{
//yyy_3y
//freopen("1.in","r",stdin);
LL n,k,p; scanf("%lld%lld%lld",&n,&k,&p);
if(k!=1)
{
mat tmp;
memset(tmp.x,0,sizeof tmp.x);
tmp.x[0][0]=k;tmp.x[0][1]=p;
tmp.x[1][0]=0;tmp.x[1][1]=1;
mat ans=Powmat(tmp,n-1);
LL an=(ans.x[0][0]+ans.x[0][1])%mod;
//debug(an);
an=an*k%mod-1-(n-1)*p%mod;
while(an<0) an+=mod;
LL res=an*mypow(k-1,mod-2)%mod;
printf("%lld\n",res);
}else
{
printf("%lld\n",(1+n*p%mod)*n%mod*mypow(2,mod-2)%mod);
}
return 0;
}