zoukankan      html  css  js  c++  java
  • HNOI2011 数学作业

    传送门

    这个题……多么希望他是可以(O(n))做的呀……取模练习题

    考虑一下用(f[i])表示到第i个数的结果,很容易得到:(f[i] = f[i-1] * 10^k + i)。其中k是当前数的位数。

    这个显然可以用矩乘优化……不过因为k是变量,所以麻烦一点……不过不要紧,对于不同位数的数我们分开做就好了。

    然后好像我的写法兼容性还不错……不是特别需要考虑什么10的指数幂之类的特例。不过我还是调了好久……因为我忘了矩乘不满足交换律……

    看一下代码。

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #include<cstring>
    #define rep(i,a,n) for(int i = a;i <= n;i++)
    #define per(i,n,a) for(int i = n;i >= a;i--)
    #define enter putchar('
    ')
    #define pr pair<int,int>
    #define mp make_pair
    #define fi first
    #define sc second
    #define fr friend inline
    using namespace std;
    typedef long long ll;
    const int M = 100005;
    const int N = 10000005;
    
    ll read()
    {
       ll ans = 0,op = 1;
       char ch = getchar();
       while(ch < '0' || ch > '9')
       {
          if(ch == '-') op = -1;
          ch = getchar();
       }
       while(ch >='0' && ch <= '9')
       {
          ans *= 10;
          ans += ch - '0';
          ch = getchar();
       }
       return ans * op;
    }
    
    ll n,m,cur = 1;
    
    struct matrix
    {
       ll f[4][4];
       matrix(){memset(f,0,sizeof(f));}
       fr matrix operator * (const matrix &a,const matrix &b)
       {
          matrix c;
          rep(i,0,2)
         rep(j,0,2)
         rep(k,0,2)
         c.f[i][j] += a.f[i][k] * b.f[k][j],c.f[i][j] %= m;
          return c;
       }
       fr matrix operator ^ (matrix a,ll b)
       {
          matrix c;
          rep(i,0,2) c.f[i][i] = 1;
          while(b)
          {
         if(b & 1) c = c * a;
         a = a * a,b >>= 1;
          }
          return c;
       }
    }F,D,E;
    
    int main()
    {
       F.f[0][1] = 1,F.f[1][1] = 1,F.f[1][2] = 1,F.f[2][2] = 1;
       D.f[1][0] = D.f[2][0] = 1;
       n = read(),m = read();
       while(n >= pow(10,cur))
       {
          F.f[0][0] = (ll)pow(10,cur) % m;
          D = (F ^ (ll)(pow(10,cur) - (ll)pow(10,cur-1))) * D;
          cur++;
       }
       n -= (ll)pow(10,cur-1);
       F.f[0][0] = (ll)pow(10,cur) % m;
       F = F ^ (n+1),D = F * D;
       printf("%lld
    ",D.f[0][0]);
       return 0;
    }
    
    
  • 相关阅读:
    Update语句到底是如何操作记录的?
    sp_helptext输出错行问题解决
    SSMS查询快捷方式设置
    快速定义临时表或表变量
    T-SQL逻辑查询
    基于交换的排序算法
    插入排序及其扩展
    Python之django基础第一天,认识django
    flask虚拟环境的安装和注意事项
    Linux基础
  • 原文地址:https://www.cnblogs.com/captain1/p/10147046.html
Copyright © 2011-2022 走看看