【BZOJ2326】【HNOI2011】数学作业 [矩阵乘法][DP]

数学作业

Time Limit: 10 Sec  Memory Limit: 128 MB
[Submit][Status][Discuss]

Description

  

Input

  输入文件只有一行为用空格隔开的两个正整数N和M。

Output

  输出仅包含一个非负整数,表示Concatenate(1~N) MOD M的值。

Sample Input

  12345678910 1000000000

Sample Output

  345678910

HINT

  1<=N<=10^8 , 1<=M<=10^9

Main idea

  给定一个n,m,创造一个数字顺序连接1~n,输出这个数对m取模的值。

Solution

  n<=10^18,排除找规律的可能性,立马想到了用矩阵乘法优化DP,令f[i]表示1~i的值,那么:

  然后我们只要推出矩阵即可,轻松想到了:

  然后分段矩乘得到答案。

Code

 1 #include<iostream>  
 2 #include<string>  
 3 #include<algorithm>  
 4 #include<cstdio>  
 5 #include<cstring>  
 6 #include<cstdlib>  
 7 #include<cmath>  
 8 using namespace std;  
 9  
10 const int ONE=5;
11  
12 long long n,MOD;
13 long long a[ONE][ONE],b[ONE][ONE];
14 long long Index;
15  
16  
17 void Mul(long long a[ONE][ONE],long long b[ONE][ONE],long long ans[ONE][ONE])
18 {
19         long long jilu[ONE][ONE];
20         for(int i=1;i<=3;i++)
21         for(int j=1;j<=3;j++)
22         {
23             jilu[i][j]=0;
24             for(int k=1;k<=3;k++)
25             jilu[i][j]=(jilu[i][j] + a[i][k]*b[k][j]%MOD) % MOD;
26         }
27          
28         for(int i=1;i<=3;i++)
29         for(int j=1;j<=3;j++)
30         ans[i][j]=jilu[i][j];
31 }
32  
33 void Matrix(long long a[ONE][ONE],long long b[ONE][ONE],long long t)
34 {
35         while(t)
36         {
37             if(t&1) Mul(a,b,a);
38             Mul(b,b,b);
39             t>>=1;
40         }
41 }
42  
43 int main()
44 {
45         cin>>n>>MOD;
46         a[1][3]=1;
47          
48         long long len=1;
49         for(;;)
50         {
51             len*=10;
52             memset(b,0,sizeof(b));
53             for(int i=1;i<=3;i++)
54             {
55                 for(int j=1;j<=i;j++)
56                 b[i][j]=1;  
57             }
58             b[1][1]=len % MOD;
59              
60             if(len<=n) Index=len-len/10;
61             else Index=n-len/10+1;
62             Matrix(a,b,Index);
63             if(len>n) break;
64         }
65          
66         printf("%lld",a[1][1]);
67 }
View Code
原文地址:https://www.cnblogs.com/BearChild/p/6441341.html