QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#19506#1423. BinqingaodongAC ✓4595ms45524kbC++205.5kb2022-02-02 11:03:182022-05-06 05:36:33

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2022-05-06 05:36:33]
  • 评测
  • 测评结果:AC
  • 用时:4595ms
  • 内存:45524kb
  • [2022-02-02 11:03:18]
  • 提交

answer

#pragma GCC optimize("O3")
#include <iostream>
#include <complex>
#include <vector>
#include <string>
#include <algorithm>
#include <cstdio>
#include <numeric>
#include <cstring>
#include <ctime>
#include <cstdlib>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <list>
#include <cmath>
#include <bitset>
#include <cassert>
#include <queue>
#include <stack>
#include <deque>
#include <random>
#include <climits>
#include <iomanip>

using namespace std;

typedef long long ll;
typedef long double ld;
#define TIME (clock() * 1.0 / CLOCKS_PER_SEC)

const int M = 1e6 + 239;
const int MOD = 998244353;
const ll MOD2 = (ll)MOD * (ll)MOD;

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

int power(int a, int b) {
    int ans = 1;
    while (b) {
        if (b & 1) ans = mul(ans, a);
        a = mul(a, a);
        b >>= 1;
    }
    return ans;
}

const int wp = power(3, 7 * 17); // w^(2^23) == 1


namespace fft {
    int k;
    vector<int> rev;
    vector<int> st;

    void fft(vector<int> &a) {
        for (int i = 0; i < k; i++)
            if (rev[i] < i)
                swap(a[rev[i]], a[i]);
        int w, wn, ai, aj;
        for (int s = 1, it = 0; s < k; s <<= 1, it++) {
            wn = st[it];
            for (int l = 0; l < k; l += s + s) {
                w = 1;
                for (int i = l, j = l + s; i < l + s; i++, j++) {
                    ai = a[i];
                    aj = 1LL * w * a[j] % MOD; // or st[((1 << 22) / s) * (i - l)]
                    a[i] = ai + aj;
                    if (a[i] >= MOD)
                        a[i] -= MOD;
                    a[j] = ai - aj;
                    if (a[j] < 0)
                        a[j] += MOD;
                    w = 1LL * w * wn % MOD;
                }
            }
        }
    }

    vector<int> mult(vector<int> a, vector<int> b) {
        k = 1;
        while (k < (int)a.size() + (int)b.size() - 1)
            k <<= 1;
        st.clear();
        st.push_back(power(wp, ((1 << 22) / k)));
        for (int t = 1; t < k; t <<= 1)
            st.push_back(1LL * st.back() * st.back() % MOD);
        reverse(st.begin(), st.end());
        rev.clear();
        rev.resize(k);
        rev[0] = 0;
        for (int i = 1; i < k; i++) {
            if (i & 1)
                rev[i] = rev[i - 1] + (k >> 1);
            else
                rev[i] = rev[i >> 1] >> 1;
        }
        a.resize(k);
        fft(a);
        b.resize(k);
        fft(b);
        vector<int> pr(k);
        for (int i = 0; i < k; i++)
            pr[i] = 1LL * a[i] * b[i] % MOD;
        fft(pr);
        reverse(pr.begin() + 1, pr.end());
        int inv_k = power(k, MOD - 2);
        for (int i = 0; i < k; i++)
            pr[i] = 1LL * pr[i] * inv_k % MOD;
        while (pr.back() == 0)
            pr.pop_back(); // can be removed
        return pr;
    }
}

int n, k;

const int MG = 15000;

const int MM = 1.1e6;

int c[MM * 2];
int dp[MM];

vector<int> values[30];
vector<pair<int, int>> cur;

int main() {
#ifdef ONPC
    freopen("input", "r", stdin);
#endif
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    cin >> n >> k;
    dp[0] = 0;
    cur = {{0, 1}};
    for (int i = 1; i <= n; i++)
    {
        ll sum = 0;
        for (int x = max(0, (i / 2) - k); x <= min(i - 1, (i / 2) + k); x++)
            if (abs(x - (i - x)) <= k)
            {
                sum += (ll)dp[x] * dp[i - x];
                if (sum >= MOD2)
                    sum -= MOD2;
            }
        dp[i] = ((c[i] % MOD) + (sum % MOD));
        if (dp[i] >= MOD)
            dp[i] -= MOD;
        if (dp[i] & 1)
            dp[i] += MOD;
        dp[i] /= 2;
        if (i == 1) dp[i] = 1;
//        cout << "!!!!" << dp[i] << ' ' << c[i] << ' ' << sum << '\n';
        cur.push_back({i, 1});
        while (cur.size() >= 2 && cur.back().second == cur[cur.size() - 2].second) {
            int id = cur.size() - 2;
            for (int j = 0; j < values[id].size(); ++j) {
                c[j + cur[id].first] -= values[id][j];
                if (c[j + cur[id].first] < 0) {
                    c[j + cur[id].first] += MOD;
                }
            }
            values[id].clear();
            cur[id].second <<= 1;
            cur.pop_back();
        }
        vector<int> a, b;
//        for (auto [a, b] : cur) {
//            cout << a << ' ' << b << '\n';
//        }
        for (int j = 0; j < cur.back().second * 2 && j <= i; ++j) {
            a.push_back(dp[j]);
        }
        for (int j = 0; j < cur.back().second; ++j) {
            b.push_back(dp[cur.back().first + j]);
        }
        values[cur.size() - 1] = fft::mult(a, b);
        int id = cur.size() - 1;
        if (cur.size() != 1) {
            for (auto &i : values[id]) {
                i += i;
                if (i >= MOD) {
                    i -= MOD;
                }
            }
        }
        for (int j = 0; j < values[id].size(); ++j) {
            c[j + cur[id].first] += values[id][j];
            if (c[j + cur[id].first] >= MOD) {
                c[j + cur[id].first] -= MOD;
            }
        }
//        for (auto j : values[id])cout << j << ' ';cout << '\n';
//        for (auto j : a)cout << j << '.';cout << '\n';
//        for (auto j : b)cout << j << '.';cout << '\n';
    }
    cout << dp[n] << "\n";
    cerr << TIME << "\n";
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 5808kb

input:

2 0

output:

1

result:

ok 1 number(s): "1"

Test #2:

score: 0
Accepted
time: 0ms
memory: 5900kb

input:

3 0

output:

1

result:

ok 1 number(s): "1"

Test #3:

score: 0
Accepted
time: 0ms
memory: 5900kb

input:

3 1

output:

2

result:

ok 1 number(s): "2"

Test #4:

score: 0
Accepted
time: 0ms
memory: 5896kb

input:

4 0

output:

2

result:

ok 1 number(s): "2"

Test #5:

score: 0
Accepted
time: 3ms
memory: 5856kb

input:

4 1

output:

3

result:

ok 1 number(s): "3"

Test #6:

score: 0
Accepted
time: 0ms
memory: 5764kb

input:

4 2

output:

5

result:

ok 1 number(s): "5"

Test #7:

score: 0
Accepted
time: 3ms
memory: 5900kb

input:

6 2

output:

23

result:

ok 1 number(s): "23"

Test #8:

score: 0
Accepted
time: 0ms
memory: 5956kb

input:

7 42

output:

132

result:

ok 1 number(s): "132"

Test #9:

score: 0
Accepted
time: 3ms
memory: 5900kb

input:

10 1

output:

400

result:

ok 1 number(s): "400"

Test #10:

score: 0
Accepted
time: 3ms
memory: 5852kb

input:

13 4

output:

42003

result:

ok 1 number(s): "42003"

Test #11:

score: 0
Accepted
time: 4ms
memory: 5844kb

input:

239 17

output:

385818773

result:

ok 1 number(s): "385818773"

Test #12:

score: 0
Accepted
time: 171ms
memory: 9468kb

input:

50216 58

output:

744498776

result:

ok 1 number(s): "744498776"

Test #13:

score: 0
Accepted
time: 3654ms
memory: 45440kb

input:

787788 78

output:

394429402

result:

ok 1 number(s): "394429402"

Test #14:

score: 0
Accepted
time: 3ms
memory: 5908kb

input:

5 92

output:

14

result:

ok 1 number(s): "14"

Test #15:

score: 0
Accepted
time: 3ms
memory: 5856kb

input:

88 79

output:

931161641

result:

ok 1 number(s): "931161641"

Test #16:

score: 0
Accepted
time: 1ms
memory: 5804kb

input:

749 77

output:

615055472

result:

ok 1 number(s): "615055472"

Test #17:

score: 0
Accepted
time: 4ms
memory: 6040kb

input:

2281 89

output:

282226588

result:

ok 1 number(s): "282226588"

Test #18:

score: 0
Accepted
time: 8ms
memory: 5912kb

input:

5765 35

output:

293680396

result:

ok 1 number(s): "293680396"

Test #19:

score: 0
Accepted
time: 132ms
memory: 9604kb

input:

43189 12

output:

805295564

result:

ok 1 number(s): "805295564"

Test #20:

score: 0
Accepted
time: 3539ms
memory: 45256kb

input:

806855 5

output:

593114139

result:

ok 1 number(s): "593114139"

Test #21:

score: 0
Accepted
time: 4414ms
memory: 45464kb

input:

994514 45

output:

678426421

result:

ok 1 number(s): "678426421"

Test #22:

score: 0
Accepted
time: 4486ms
memory: 45464kb

input:

999921 62

output:

752162081

result:

ok 1 number(s): "752162081"

Test #23:

score: 0
Accepted
time: 4574ms
memory: 45424kb

input:

995033 94

output:

130314865

result:

ok 1 number(s): "130314865"

Test #24:

score: 0
Accepted
time: 4138ms
memory: 45524kb

input:

901438 97

output:

809128292

result:

ok 1 number(s): "809128292"

Test #25:

score: 0
Accepted
time: 4308ms
memory: 45428kb

input:

993020 0

output:

926771801

result:

ok 1 number(s): "926771801"

Test #26:

score: 0
Accepted
time: 4595ms
memory: 45428kb

input:

1000000 100

output:

470305140

result:

ok 1 number(s): "470305140"