QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#343463#6187. Digit Sum Problemucup-team1198#AC ✓1769ms114000kbC++204.7kb2024-03-02 16:41:402024-03-02 16:41:41

Judging History

你现在查看的是最新测评结果

  • [2024-03-02 16:41:41]
  • 评测
  • 测评结果:AC
  • 用时:1769ms
  • 内存:114000kb
  • [2024-03-02 16:41:40]
  • 提交

answer

#include <map>
#include <set>
#include <array>
#include <cmath>
#include <deque>
#include <bitset>
#include <random>
#include <string>
#include <vector>
#include <cassert>
#include <complex>
#include <iomanip>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <unordered_set>

using namespace std;

const int MOD = 998244353;

int add(int a, int b) {
    if (a + b < MOD)
        return a + b;
    return a + b - MOD;
}

int sub(int a, int b) {
    if (a >= b)
        return a - b;
    return a + MOD - b;
}

int mul(int a, int b) {
    return a * 1ll * b % MOD;
}

int pw(int a, long long n) {
    int ans = 1;
    while (n) {
        if (n & 1ll)
            ans = mul(ans, a);
        n >>= 1;
        a = mul(a, a);
    }
    return ans;
}

const int G = 3;

void fft(vector<int>& a, bool inv = false) {
    int n = a.size(), k = 0;
    while ((1 << k) < n) ++k;
    static vector<int> rev, power = {0, 1};
    rev.resize(n);
    rev[0] = 0;
    for (int i = 1; i < n; ++i) {
        rev[i] = rev[i / 2] / 2 + ((i & 1) << (k - 1));
        if (i < rev[i]) {
            swap(a[i], a[rev[i]]);
        }
    }
    for (int l = 1; l < n; l *= 2) {
        if ((int)power.size() == l) {
            power.resize(2 * l);
            int w = pw(G, (MOD - 1) / 2 / l);
            for (int i = l; i < 2 * l; ++i) {
                power[i] = power[i / 2];
                if (i & 1) {
                    power[i] = mul(power[i], w);
                }
            }
        }
        for (int i = 0; i < n; i += 2 * l) {
            for (int j = 0; j < l; ++j) {
                int x = a[i + j], y = mul(a[i + j + l], power[j + l]);
                a[i + j] = add(x, y);
                a[i + j + l] = sub(x, y);
            }
        }
    }
    if (inv) {
        reverse(a.begin() + 1, a.end());
        int anti = pw(n, MOD - 2);
        for (int& x : a) x = mul(x, anti);
    }
}

vector<int> operator*(vector<int> a, vector<int> b) {
    int sz = a.size() + b.size() - 1;
    int k = 0;
    while ((1 << k) < sz) ++k;
    a.resize(1 << k);
    b.resize(1 << k);
    fft(a); fft(b);
    for (int i = 0; i < (1 << k); ++i) {
        a[i] = mul(a[i], b[i]);
    }
    fft(a, true);
    a.resize(sz);
    return a;
}

vector<int> get_pr(vector<int> A, vector<int> B) {
    /**vector<int> ans(A.size() + B.size());
    for (int i = 0; i < A.size(); ++i) {
        for (int j = 0; j < B.size(); ++j)
            ans[i + j] = add(ans[i + j], mul(A[i], B[j]));
    }
    return ans;*/
    return A * B;
}

int f(long long x) {
    int ans = 0;
    while (x) {
        ans += x & 1;
        x >>= 1;
    }
    return ans;
}

int g(long long x) {
    int ans = 0;
    while (x) {
        ans += x % 3;
        x /= 3;
    }
    return ans;
}

const int K2 = 21;
const int K3 = 13;


int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    
    long long n;
    int a, b, c;
    cin >> n >> a >> b >> c;
    long long pw3 = 1;
    for (int i = 0; i < K3; ++i)
        pw3 *= 3;
    long long pw2 = 1;
    for (int i = 0; i < K2; ++i)
        pw2 *= 2;
    vector<int> A(pw3);
    vector<int> B(pw2);
    for (int i = 0; i < pw3; ++i)
        A[i] = mul(pw(a, i), pw(c, g(i)));
    for (int i = 0; i < pw2; ++i)
        B[pw2 - i - 1] = pw(b, f(i));
    auto coeffs = get_pr(A, B);

    int ans = sub(0, 1);
    long long i = 0;
    int cur_a = 1;
    int a_pw3 = pw(a, pw3);
    for (; (i + 1) * pw3 <= n + 1; ++i) {
        // from i * pw3 to (i + 1) * pw3 - 1
        int cur_all_coeff = mul(cur_a, pw(c, g(i)));
        long long st = i * pw3;
        long long fin = (i + 1) * pw3 - 1;

        long long p = st % pw2;
        long long pr = st / pw2;
        ans = add(ans, mul(coeffs[pw2 - p - 1], mul(cur_all_coeff, pw(b, f(pr)))));
        if (pw2 - p - 1 < pw3 - 1) {
            long long q = fin % pw2;
            long long qr = fin / pw2;
            ans = add(ans, mul(coeffs[pw3 - 1 + pw2 - 1 - q], mul(cur_all_coeff, pw(b, f(qr)))));
        }
        cur_a = mul(cur_a, a_pw3);
        // cur_a = a^(i * pw3)
    }
    int anti_b = pw(b, MOD - 2);
    int anti_c2 = pw(mul(c, c), MOD - 2);
    int abc = mul(a, mul(b, c));
    int val = mul(pw(a, i * pw3), mul(pw(b, f(i * pw3)), pw(c, g(i * pw3))));
    for (long long j = i * pw3; j <= n;) {
        ans = add(ans, val);
        ++j;
        val = mul(val, abc);
        long long j2 = j;
        while (j2 % 2 == 0) {
            j2 /= 2;
            val = mul(val, anti_b);
        }
        while (j2 % 3 == 0) {
            j2 /= 3;
            val = mul(val, anti_c2);
        }
    }

    cout << ans << '\n';
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 1211ms
memory: 113952kb

input:

123456 12345 234567 3456789

output:

664963464

result:

ok 1 number(s): "664963464"

Test #2:

score: 0
Accepted
time: 1745ms
memory: 113800kb

input:

9876543210987 12816 837595 128478

output:

7972694

result:

ok 1 number(s): "7972694"

Test #3:

score: 0
Accepted
time: 1734ms
memory: 113948kb

input:

9196665971964 727160879 966835565 746444639

output:

949890012

result:

ok 1 number(s): "949890012"

Test #4:

score: 0
Accepted
time: 1730ms
memory: 113876kb

input:

9361549073598 749653880 965489817 371100607

output:

949904373

result:

ok 1 number(s): "949904373"

Test #5:

score: 0
Accepted
time: 1725ms
memory: 113864kb

input:

9567572694963 193332930 544713669 390021151

output:

878781872

result:

ok 1 number(s): "878781872"

Test #6:

score: 0
Accepted
time: 1740ms
memory: 113784kb

input:

9769301349033 215825931 425927410 408941695

output:

351574791

result:

ok 1 number(s): "351574791"

Test #7:

score: 0
Accepted
time: 1769ms
memory: 113776kb

input:

9975324970399 657749333 5151262 729852127

output:

400022780

result:

ok 1 number(s): "400022780"

Test #8:

score: 0
Accepted
time: 1205ms
memory: 114000kb

input:

1 149762920 266126484 107367523

output:

910371791

result:

ok 1 number(s): "910371791"

Test #9:

score: 0
Accepted
time: 1272ms
memory: 113996kb

input:

903900971479 969144397 356713678 36786741

output:

414279957

result:

ok 1 number(s): "414279957"

Test #10:

score: 0
Accepted
time: 1313ms
memory: 113952kb

input:

1940757501452 72683414 106545701 263512239

output:

786323834

result:

ok 1 number(s): "786323834"

Test #11:

score: 0
Accepted
time: 1358ms
memory: 113836kb

input:

2914414844884 174466783 133201789 792227626

output:

187534312

result:

ok 1 number(s): "187534312"

Test #12:

score: 0
Accepted
time: 1421ms
memory: 113876kb

input:

3851250038782 553074217 881278164 297532837

output:

847958862

result:

ok 1 number(s): "847958862"

Test #13:

score: 0
Accepted
time: 1453ms
memory: 113804kb

input:

4692374803740 352867698 211679787 826248223

output:

426334178

result:

ok 1 number(s): "426334178"

Test #14:

score: 0
Accepted
time: 1519ms
memory: 113948kb

input:

5566041306806 454651067 959756163 633543322

output:

842296050

result:

ok 1 number(s): "842296050"

Test #15:

score: 0
Accepted
time: 1579ms
memory: 113992kb

input:

6902869060611 556434437 709588186 860268821

output:

897681255

result:

ok 1 number(s): "897681255"

Test #16:

score: 0
Accepted
time: 1603ms
memory: 113800kb

input:

7239695301792 356227918 736244273 667563920

output:

726280051

result:

ok 1 number(s): "726280051"

Test #17:

score: 0
Accepted
time: 1668ms
memory: 113772kb

input:

8217660029470 458011287 486076297 198034954

output:

967159922

result:

ok 1 number(s): "967159922"