【矩阵】[HNOI2011][HYSBZ/BZOJ2326][CQBZOJ2831]数学作业

来源:互联网 发布:php高并发秒杀 实例 编辑:程序博客网 时间:2024/05/01 01:47

题目
分析:另f[n]为Concatenate(1..N) Mod M的值,那么f[n]=(f[n-1]*10^length[n]+n)%MOD。
所以

[f[n]n1]=[f[n1]n1]111011001

根据数字的长度分段做矩阵快速幂即可。

#include<cstdio>#include<algorithm>#include<cstring>using namespace std;#define MAXMT 3#define MOD mtypedef int matrix[MAXMT+1][MAXMT+1];matrix a,b;long long n;int m,ans;template<class T>void Read(T &x){    char c;    while(c=getchar(),c!=EOF)        if(c>='0'&&c<='9'){            x=c-'0';            while(c=getchar(),c>='0'&&c<='9')                x=x*10+c-'0';            ungetc(c,stdin);            return;        }}void mul(matrix a,matrix b,matrix c){    matrix d;    memset(d,0,sizeof d);    int i,j,k;    for(i=1;i<=MAXMT;i++)        for(j=1;j<=MAXMT;j++)            for(k=1;k<=MAXMT;k++)                d[i][j]=(d[i][j]+1ll*a[i][k]*b[k][j])%MOD;    memcpy(c,d,sizeof d);}void quick_pow(matrix a,long long b,matrix c){    matrix d,t;    memcpy(t,a,sizeof t);    memset(d,0,sizeof d);    for(int i=1;i<=MAXMT;i++)        d[i][i]=1;    while(b){        if(b&1)            mul(d,t,d);        mul(t,t,t);        b>>=1;    }    memcpy(c,d,sizeof d);}void solve(){    a[1][1]=a[2][1]=a[2][2]=a[3][1]=a[3][2]=a[3][3]=1;    long long t=1;    while(n>=t){        a[1][1]=1ll*a[1][1]*10%MOD;        quick_pow(a,min(n,t*10-1)-t+1,b);        ans=(1ll*ans*b[1][1]%MOD+(t-1)%MOD*b[2][1]%MOD+b[3][1])%MOD;        t*=10;    }}int main(){    Read(n),Read(m);    solve();    printf("%d\n",ans);}
0 0
原创粉丝点击