bzoj 2326: [HNOI2011]数学作业
2326: [HNOI2011]数学作业
Description
不说什么ACTY了。。
题解:
线性的递推很容易写出来,f[i]=f[i-1]*10+i (mod)
但是n很大,就需要用到矩阵乘法了。。
我们够造矩阵
10^a 1 1 f[i-1] f[i]
0 1 1 * i-1 = i
0 0 1 1 1
由于a的关系,我们按位进行矩阵乘法
#include<stdio.h> #include<iostream> #include<string.h> using namespace std; #define ll long long int i; ll n,m,s,a[4][4],b[4][4],c[4][4]; void mul(ll a[4][4],ll b[4][4],ll ans[4][4]) { int i,j,k; memset(c,0,sizeof(c)); for(i=1;i<=3;i++) for(j=1;j<=3;j++) for(k=1;k<=3;k++) c[i][j]=(c[i][j]+(a[i][k]%m)*(b[k][j]%m))%m; for(i=1;i<=3;i++) for(j=1;j<=3;j++) ans[i][j]=c[i][j]; } void solve(ll x,ll y) { y=y-x/10+1; memset(b,0,sizeof(b)); b[1][1]=x; b[1][2]=b[1][3]=b[2][2]=b[2][3]=b[3][3]=1; while(y) { if(y&1) mul(b,a,a); mul(b,b,b); y>>=1; } } int main() { cin>>n>>m; for(i=1;i<=3;i++) a[i][i]=1; s=10; while(n>=s) { solve(s,s-1); s*=10; } solve(s,n); cout<<a[1][3]; return 0; }
一念起,天涯咫尺; 一念灭,咫尺天涯。