CF1452D Radio Towers【斐波拉契】【矩阵快速幂】【逆元】

D. Radio Towers

比较简单的思维DP。画图分析一下就可以发现每座塔亮的氛围是以自己为中心的奇数格,那么递推公式和奇偶性相关,$i$为偶数时$f(i)$为$i$前面所有奇数的$f$之和,$i$为奇数时$f(i)$为$i$前面所有偶数的$f$之和,再化简一下就可以发现对于所有$i$都是$f(i)=f(i-2)+f(i-1)$,这道题实质就是斐波拉契数列。

或许如果数据范围是long long就能直接往这方面想了,或许还要更简单一点?()

主要是复习了矩阵快速幂和逆元,从$cjhdalao$那里学到了define int long long+signed main,非常好用吼,治疗了看瞎都找不出来的超范围问题,随手A了洛谷。

#include<bits/stdc++.h>
#define int long long
#define mod 998244353
using namespace std;

struct Matrix {
    int w[3][3];
} base;

Matrix Cheng(Matrix a, Matrix b) {
    Matrix ans;
    for(int i = 1; i <= 2; i ++)
        for(int j = 1; j <= 2; j ++)
            ans.w[i][j] = 0;
    for(int i = 1; i <= 2; i ++)
        for(int j = 1; j <= 2; j ++)
            for(int k = 1; k <= 2; k ++)
            ans.w[i][j] = (ans.w[i][j] + a.w[i][k] * b.w[k][j] % mod) % mod;
    return ans;
}

Matrix Mpow(Matrix a, int b) {
    Matrix ans;
    for(int i = 1; i <= 2; i ++)
        for(int j = 1; j <= 2; j ++)
            ans.w[i][j] = i == j ? 1 : 0;
    for( ; b; b >>= 1, a = Cheng(a, a))
        if(b & 1)    ans = Cheng(ans, a);
    return ans;
}

int mpow(int a, int b) {
    int ans = 1;
    for( ; b; a = a * a % mod, b >>= 1)
        if(b & 1)    ans = ans * a % mod;
    return ans;
}

int inv(int a, int p) {
    return mpow(a, p - 2);
}

signed main() {
    int n;
    scanf("%lld", &n);
    if(n == 1) {
        printf("%lld", inv(mpow(2, n), mod) % mod);
    } else {
        base.w[1][1] = base.w[1][2] = base.w[2][1] = 1;
        base.w[2][2] = 0;
        base = Mpow(base, n - 2);
        int ans = (base.w[1][1] + base.w[1][2]) % mod;
        ans = ans * inv(mpow(2, n), mod) % mod;
        printf("%lld", ans);
    }
    return 0;
}

和大佬们面基了,睿神边想边写直接A掉4道真的tql,贺神会好多高级的语法而且一直用的vim,刷了题去ccss吃了夜宵,更坚定了我躺的信心。

但是大家都好懒喔。都是咕神。

对了,队名叫:欺负我们小同志($You'd$ $better$ $rat$ $tail$ $juice!$)

posted @ 2020-11-28 23:05  Wans_ovo  阅读(112)  评论(0编辑  收藏  举报