JZOJ 1351. 阅读程序写结果
题目
分析
- 首先我们可以知道
- $\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; }
为何要逼自己长大,去闯不该闯的荒唐