WA #8 求调
查看原帖
WA #8 求调
602372
Brilliant11001楼主2024/8/31 20:37

rt,一开始是精度的问题,结果改成 long double 后还是 WA。

#include <cmath>
#include <cstring>
#include <iostream>

using namespace std;

const int N = 3, M = 20;
typedef unsigned long long ll;

ll n;
int m;

struct Matrix{
    ll mar[N][N];
    Matrix() {memset(mar, 0, sizeof mar);}
    void init() {mar[0][0] = mar[1][1] = mar[2][2] = 1;}
    Matrix operator *(const Matrix &o) const{
        Matrix res;
        for(int i = 0; i < N; i++)
            for(int j = 0; j < N; j++)
                for(int k = 0; k < N; k++)
                    res.mar[i][j] = (res.mar[i][j] + (__int128)mar[i][k] % m * o.mar[k][j] % m) % m;
        return res;
    }
}A, res;
ll power10[M];

Matrix qpow(Matrix a, ll b) {
    Matrix res;
    res.init();
    while(b) {
        if(b & 1) res = res * a;
        a = a * a;
        b >>= 1;
    }
    return res;
}

int main() {
    scanf("%llu%d", &n, &m);
    power10[0] = 1;
    for(int i = 1; i <= 18; i++)
        power10[i] = power10[i - 1] * 10;
    int limit = (int)log10((long double)n);
    res.mar[0][0] = res.mar[0][2] = 1, res.mar[0][1] = 2;

    A.mar[0][0] = 10, A.mar[0][1] = 0, A.mar[0][2] = 0;
    A.mar[1][0] = 1, A.mar[1][1] = 1, A.mar[1][2] = 0;
    A.mar[2][0] = 0, A.mar[2][1] = 1, A.mar[2][2] = 1;

    for(int i = 0; i < limit; i++) {
        res = res * qpow(A, power10[i + 1] - power10[i] - 1);
        A.mar[0][0] = power10[i + 2] % m;
        res = res * A;
    }

    res = res * qpow(A, n - power10[limit]);

    printf("%llu\n", res.mar[0][0]);
    return 0;
}
/*
99999999999999999 1000000000
*/
2024/8/31 20:37
加载中...