[HNOI2011]数学作业 题解

  这道题看着挺难然而其实看破了也挺容易的。首先N极其的大,几乎要炸掉long long ,所以O(n)的算法一定是扑街了,身为一个脑残志坚的OIer,怎能不想到矩阵快速幂优化呢? 

  有趣的是这道题矩阵有很多种,Q某犇有另一种做法,大家也可以去他那看一看。

  答案矩阵是这样的:

    f[x]   x+1   1

  被我们用来求答案的矩阵长这样:

    10^t     0      0

    1         1      0

    0         1      1

   其中t随我们现在处理的数的位数而改变。

  然后这道题就硬生生的被我们搞成了一个矩阵快速幂的裸题。只要注意矩阵乘不满足交换律就是了。

  

 1 #include<iostream>
 2 #include<cstdlib>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<algorithm>
 6 #include<map>
 7 #include<queue>
 8 #include<string>
 9 #include<cmath>
10 using namespace std;
11 long long n,m;
12 struct no{
13     long long x,y;
14     long long a[20][20];
15     no operator *(const no &c){
16         no b;
17         memset(b.a,0,sizeof(b.a));
18         b.x=x;
19         b.y=y;
20         for(int i=1;i<=x;i++)
21         {
22             for(int j=1;j<=y;j++)
23             {
24                 for(int k=1;k<=y;k++)
25                 {
26                     b.a[i][j]+=((a[i][k]%m)*(c.a[k][j]%m))%m;
27                     b.a[i][j]%=m;
28                 }
29             }
30         }
31         return b;
32     }
33 };
34 no ksm(long long x,no a,no b){
35     no ans=a;
36     while(x)
37     {
38         if((x&1)) ans=ans*b;
39         b=b*b;
40         x>>=1;
41     }
42     return ans;
43 }
44 long long get(long long x){
45     long long now=1;
46     no ans,a;
47     memset(a.a,0,sizeof(a.a));
48     a.x=a.y=3;
49     a.a[2][1]=a.a[2][2]=a.a[3][2]=a.a[3][3]=1;
50     memset(ans.a,0,sizeof(ans.a));
51     ans.x=1,ans.y=3;
52     ans.a[1][1]=0;
53     ans.a[1][2]=ans.a[1][3]=1;
54     for(int i=1;;i++)
55     {
56         now*=10;
57         if(x>(now-1))
58         {
59             a.a[1][1]=now;
60             ans=ksm(now-now/10,ans,a);
61         }
62         else
63         {
64             a.a[1][1]=now;
65             ans=ksm(x-(now/10-1),ans,a);
66             break;
67         }
68     }
69     return ans.a[1][1];
70 }
71 int main(){
72     scanf("%lld%lld",&n,&m);
73     printf("%lld
",get(n));
74     //while(1);
75     return 0;
76 }
View Code
原文地址:https://www.cnblogs.com/liutianrui/p/7360281.html