您的位置:首页 > 其它

[bzoj2326][HNOI2011]数学作业

2017-04-18 09:55 387 查看
来自FallDream的博客,未经允许,请勿转载,谢谢。



一个数接在后面的时候我们都可以看作乘以10的对应次方再加上这个数,所以考虑构造关于f(x),x矩阵,每次x还要加1,所以变成

(f[x] ) (10^k) ( 1 ) ( 1 ) (f[x+1])

( x ) * ( 0 ) ( 1 ) ( 1 ) = ( x+1 )

( 1 )   ( 0 ) ( 0 ) ( 1 ) ( 1 )

对于不同的k分开处理

#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
inline ll read()
{
ll x = 0 , f = 1; char ch = getchar();
while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}
while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
return x * f;
}

int mod,pw[19];
ll n;
struct Matrix
{
int s[4][4],r,c;
Matrix(){memset(s,0,sizeof(s));}
Matrix(int y)
{
memset(s,0,sizeof(s));r=c=3;
s[1][1]=pw[y];s[1][2]=s[1][3]=1;
s[2][3]=s[2][2]=s[3][3]=1;
}
Matrix(int a,int b)
{
memset(s,0,sizeof(s));r=3;c=1;
s[1][1]=a;s[2][1]=b;s[3][1]=1;
}
Matrix operator*(Matrix b)
{
Matrix d;d.r=r;d.c=b.c;
for(int i=1;i<=r;i++)
for(int j=1;j<=c;j++)
for(int k=1;k<=b.c;k++)
d.s[i][k]=(d.s[i][k]+1LL*s[i][j]*b.s[j][k])%mod;
return d;
}
}a(0,0);

void solve(int k,ll c)
{
Matrix b(k);
for(;c;c>>=1,b=b*b)
if(c&1) a=b*a;
}

int main()
{
n=read();mod=read();
pw[1]=10%mod;
for(int i=2;i<=18;i++) pw[i]=1LL*pw[i-1]*10%mod;
for(ll i=9,last=0,j=1;n>last;++j,last=i,i=i*10+9)
solve(j,min(i,n)-last);
printf("%d\n",a.s[1][1]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: