题目
分析
- 首先我们可以知道
- $sum_{i=1}^{n}qquad q^i*q $这个就是我们要求的
- 直接算有50
- 我们考虑用矩阵快速幂优化
- 设矩阵为$[p^i,p^i*i,sum[i-1]]$
- 我们推得$p^(i+1)*(i+1)=p^i*p+p^i*p
- 我们列出矩阵
- | p p 0 |
- | 0 p 1 |
- | 0 0 1 |
- 乘出来就好了
- 因为只有一行
- 每一次都乘一列加起来
代码
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define ll long long
const int mo = 2009;
using namespace std;
int h[1020],cnt;
struct sb
{
int a[3][3];
};
sb x;
int ans[3];
bool check()
{
for (int i=1;i<=1000;i++)
if (h[i]!=0) return false;
return true;
}
sb mul(sb x,sb y)
{
sb res;
memset(res.a,0,sizeof(res));
for (int i=0;i<3;i++)
for (int j=0;j<3;j++)
for (int k=0;k<3;k++)
res.a[i][j]=(res.a[i][j]+x.a[i][k]*y.a[k][j])%mo;
return res;
}
void mull()
{
ll c[3];memset(c,0,sizeof(c));
for(ll i=0;i<=2;i++)for(ll j=0;j<=2;j++)c[i]=(c[i]+x.a[j][i]*ans[j]%mo)%mo;
for (int i=0;i<=2;i++) ans[i]=c[i];
}
void div()
{
int wz=1;
while (h[wz]==0) wz++;
int r=0,t;
for (int i=wz;i<=cnt;i++)
{
t=h[i];
h[i]=(r*10+h[i])/2;
r=(r*10+t)%2;
}
}
int main()
{
char c;
c=getchar();
while (c!=' ')
{
h[++cnt]=c-'0';
c=getchar();
}
int p;
cin>>p;
memset(x.a,0,sizeof(x));
ans[0]=ans[1]=p;
x.a[0][0]=p; x.a[0][1]=p; x.a[1][1]=p; x.a[1][2]=1; x.a[2][2]=1;
while (!check())
{
if (h[cnt]&1!=0) mull();
x=mul(x,x);
div();
}
cout<<ans[2];
return 0;
}