头铁来源
因为狼胆小编本人比较垃圾,所以只能每天带大家头铁一题简单常识题(大佬眼中的常识,我这个蒟蒻还只能头铁),希望能帮助到小白,那就很开心了
题目
题目链接
2019牛客多校5 B题

题解
理想中的草稿状态

真实的草稿状态

dreammoon大佬的官方的题解也可以看看

AC代码
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
 | #include<bits/stdc++.h>
typedef unsigned long long ULL;
const int SIZE = 3000010;
ULL MOD;
char s[SIZE];
/*矩阵相乘,第一行乘以第一列,第一行乘以第二列……也可以使用for两重循环求*/
void mul(ULL* c1, ULL* c2, ULL *res){
    res[0] = (c1[0] * c2[0] + c1[1] * c2[2]) % MOD;
    res[1] = (c1[0] * c2[1] + c1[1] * c2[3]) % MOD;
    res[2] = (c1[2] * c2[0] + c1[3] * c2[2]) % MOD;
    res[3] = (c1[3] * c2[3] + c1[2] * c2[1]) % MOD;
}
int main() {
    int a,b;
    int x1,x2;
    scanf("%d%d%d%d", &x1, &x2, &a, &b);
    scanf("%s%llu",s, &MOD);
    int len = 0;
    /* 统计长度,并且把个位的值(即最后一位的值)减去1 */
    for(; s[len]; len++);
    s[len-1]--;
    /* 个位减掉了之后向前面借位 */
    for(int i = len - 1; i >= 0 && s[i] < '0'; i--){
        s[i] = '9';
        s[i-1]--;
    }
    ULL now0 = x1, now1 = x2;
    ULL d[4][4];
    d[0][0] = 0;
    d[0][1] = 1;
    d[0][2] = b;
    d[0][3] = a;
    for(int it = len - 1; it >= 0; it--){
        memset(d[1], 0, sizeof(ULL) * 12);
        /*A "常数"矩阵相乘4次*/
        for(int p = 1; p < 4; p++){
            mul(d[p-1], d[p-1], d[p]);
        }
        s[it] -= '0';
        for(int p = 0; p < 4; p++){
            if((s[it] >> p) & 1){
                ULL* ml = d[p];
                std::tie(now0, now1) = std::make_pair((ml[0] * now0 + ml[1] * now1) % MOD,(ml[2] * now0 + ml[3] * now1) % MOD);
            }
        }
        mul(d[1], d[3], d[0]);
    }
    printf("%llu\n", now1);
    return 0;
}
 | 
 
少量知识点
tie
pair是tuple的一个子集
每天一句叨叨
今天看到一禅小和尚: 我们尝遍生活的苦,却都只是为了过好平凡的一生
但我觉得如果自己明知道人生是苦,明知道人是基因的机器人(参见算法日常4的叨叨),却认认认真真地选择好好生活,这就是一种伟大,这就是自由,这就是自己的突破,就是自己的英雄!