• [AHOI2004]数字迷阵


    瞪眼观察题。发现行列都跟斐波那契数列有关。

    如果能求出第一列就好了。

    发现第一列的数都是由若干个$2$和若干$3$的和加$1$。

    发现第$fib[i]$行有$fib[i-2]$个3和$fib[i-3]$个2。

    其他行呢?

    将行号拆分成若干项斐波那契数列的和,发现对应的$3$、$2$的数目也是对应的和。

    然后万事大吉了。

    距离$AC$还只需要会矩阵快速幂。

    感性理解代码。

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 #define re register
     6 #define rep(i, a, b) for (re int i = a; i <= b; ++i)
     7 #define repd(i, a, b) for (re int i = a; i >= b; --i)
     8 #define For(i, a, b, s) for (re int i = a; i <= b; s)
     9 #define maxx(a, b) a = max(a, b)
    10 #define minn(a, b) a = min(a, b)
    11 #define LL long long
    12 #define INF (1 << 30)
    13 
    14 inline int read() {
    15     int w = 0, f = 1; char c = getchar();
    16     while (!isdigit(c)) f = c == '-' ? -1 : f, c = getchar();
    17     while (isdigit(c)) w = (w << 3) + (w << 1) + (c ^ '0'), c = getchar();
    18     return w * f;
    19 }
    20 
    21 const int MAX = 1000000000;
    22 
    23 struct Matrix {
    24     int a, b, c, d;
    25     // | a b |
    26     // | c d |
    27 } f, g;
    28 
    29 int fib[100], x, y, P;
    30 int a, b;
    31 
    32 Matrix operator * (Matrix a, Matrix b) {
    33     Matrix res;
    34     res.a = (a.a * b.a + a.b * b.c) % P;
    35     res.b = (a.a * b.b + a.b * b.d) % P;
    36     res.c = (a.c * b.a + a.d * b.c) % P;
    37     res.d = (a.c * b.b + a.d * b.d) % P;
    38     return res;
    39 }
    40 
    41 int main() {
    42     fib[1] = fib[2] = 1;
    43     int X = x = read()-1; y = read(), P = read();
    44     int i;
    45     for (i = 3; fib[i-1] <= x; i++) fib[i] = fib[i-1] + fib[i-2];
    46     while (i--)
    47         if (fib[i] <= x) x -= fib[i], a = (a + 3 * fib[i-1]) % P, b = (b + 2 * fib[i-2]) % P;
    48     a = (a+b+1) % P, b = (a*2ll+(LL)X*P-X) % P;
    49     if (y < 3) printf("%d", y == 1 ? a : b);
    50     else {
    51         g.a = g.b = g.c = 1; g.d = 0;
    52         f.a = f.d = 1; f.b = f.c = 0;
    53         y -= 2;
    54         while (y) {
    55             if (y & 1) f = f * g;
    56             g = g * g;
    57             y >>= 1;
    58         }
    59         printf("%d", (f.b * a + f.a * b) % P);
    60     }
    61     return 0;
    62 }
  • 相关阅读:
    简单的理解原型链
    react->Context笔记
    工作上git指令小结
    vue 绑定事件如何传递参数的同时拿到事件对象
    vsCode卸载后重新安装,以前的插件有没有效果的解决方法
    mongo 分组 aggregation
    Redisson分布式锁原理
    Virtual server server already has a web module live-mix-1.0.2-t230 loaded at / therefore web module
    二进制中 1 的个数
    替换空格
  • 原文地址:https://www.cnblogs.com/ac-evil/p/10501686.html
Copyright © 2020-2023  润新知