复杂度正确,但是不开O2只有80pts
查看原帖
复杂度正确,但是不开O2只有80pts
1074084
asd890123楼主2024/8/11 16:50

时间复杂度O(log⁡10n+log⁡10m)O(\log_{10}n+\log_{10}m),只有2×1062 \times 10^6,按理说可以轻松过,但是我也知道常数比较大,乘法大约循环23=82^3 = 8次,然后十进制快速幂内部循环要做9到18次乘法,常数在7272到144144左右,但是按理说极限情况带常数也就2.88∗1082.88 * 10^8,极限10910^9的洛谷应该能过啊,为啥过不了,code:

#include <iostream>
#include <cstring>

const int N = 1000005,mod = 1e9 + 7;

char n[N],m[N];

struct matrix{

    int n,m,a[3][3];

    matrix():n(0),m(0){memset(a,0,sizeof(a));}
    matrix(int _n):n(_n),m(_n){

        memset(a,0,sizeof(a));
        for (int i = 1;i <= n;i++) a[i][i] = 1;

    }
    matrix(int _n,int _m):n(_n),m(_m){memset(a,0,sizeof(a));}
    int* operator[](int i){return a[i];}
    matrix operator*=(matrix x){return *this = *this * x;}

    matrix operator*(matrix x){

        matrix c(n,x.m);

        for (int i = 1;i <= c.n;i++)
            for (int j = 1;j <= c.m;j++)
                for (int k = 1;k <= m;k++)    
                    c[i][j] = (c[i][j] + (long long)a[i][k] * x[k][j]) % mod;

        return c;
    }

    matrix qpow(char* b){

        matrix ans(n),a = *this;

        for (int l = strlen(b + 1);l;l--){

            matrix tmp = a;

            for (int i = 1;i <= b[l] - '0';i++) ans *= a;
            for (int i = 1;i <= 9;i++) a *= tmp;

        }

        return ans;
    }

};

int main(){

    std::cin.tie(0)->sync_with_stdio(0);

    int a,b,c,d;

    std::cin >> n + 1 >> m + 1 >> a >> b >> c >> d;
    for (int i = strlen(n + 1);i;i--){

        if (n[i] == '0') n[i] = '9';
        else{

            n[i] = n[i] - 1;
            break;
            
        }

    }
    for (int i = strlen(m + 1);i;i--){

        if (m[i] == '0') m[i] = '9';
        else{

            m[i] = m[i] - 1;
            break;
            
        }

    }
    matrix A(2,2),B(2,2),C(2,1);
    A[1][1] = a;
    A[1][2] = b;
    A[2][1] = 0;
    A[2][2] = 1;
    B[1][1] = c;
    B[1][2] = d;
    B[2][1] = 0;
    B[2][2] = 1;
    C[1][1] = 1;
    C[2][1] = 1;
    std::cout << (A.qpow(m) * (B * A.qpow(m)).qpow(n) * C)[1][1] << '\n';

    return 0;
}

不开O2O2最后44个TLETLE。 请求添加标签O2O2优化。

2024/8/11 16:50
加载中...