QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#262798#4491. Find the Number of Pathsucup-team1198AC ✓4749ms43220kbC++145.1kb2023-11-24 03:19:062023-11-24 03:19:06

Judging History

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

  • [2023-11-24 03:19:06]
  • 评测
  • 测评结果:AC
  • 用时:4749ms
  • 内存:43220kb
  • [2023-11-24 03:19:06]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;

const int MOD = 998244353;

int add(int a, int b) {
    return a + b >= MOD ? a + b - MOD : a + b;
}

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

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

int pw(int x, int n) {
    int res = 1;
    while (n) {
        if (n % 2 == 0) {
            x = mul(x, x);
            n /= 2;
        } else {
            res = mul(res, x);
            n--;
        }
    }
    return res;
}

const int G = 3;

void fft(vector<int>& a, bool inv = false) {
    int n = a.size();
    int 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) {
        int anti = pw(n, MOD - 2);
        reverse(a.begin() + 1, a.end());
        for (int i = 0; i < n; ++i) {
            a[i] = mul(a[i], 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> operator+(const vector<int>& a, const vector<int>& b) {
    vector<int> c(max(a.size(), b.size()));
    for (int i = 0; i < (int)a.size(); ++i) {
        c[i] = a[i];
    }
    for (int i = 0; i < (int)b.size(); ++i) {
        c[i] = add(c[i], b[i]);
    }
    return c;
}

vector<int> operator-(const vector<int>& a, const vector<int>& b) {
    vector<int> c(max(a.size(), b.size()));
    for (int i = 0; i < (int)a.size(); ++i) {
        c[i] = a[i];
    }
    for (int i = 0; i < (int)b.size(); ++i) {
        c[i] = sub(c[i], b[i]);
    }
    return c;
}

vector<int> inv(vector<int> a, int n) {
    vector<int> b = {pw(a[0], MOD - 2)};
    static vector<int> a1;
    int m = 1;
    while (m < n) {
        a1.resize(2 * m);
        fill(a1.begin(), a1.end(), 0);
        for (int i = 0; i < (int)a.size() && i < 2 * m; ++i) {
            a1[i] = a[i];
        }
        b = b + b - a1 * b * b;
        b.resize(2 * m);
        m *= 2;
    }
    b.resize(n);
    return b;
}

const int MAXF = 2e6;
int fact[MAXF], invf[MAXF];

vector<int> der(vector<int> a) {
    if ((int)a.size() == 1) {
        return {0};
    }
    for (int i = 1; i < (int)a.size(); ++i) {
        a[i - 1] = mul(i, a[i]);
    }
    a.pop_back();
    return a;
}

vector<int> integ(vector<int> a) {
    a.push_back(0);
    for (int i = (int)a.size() - 2; i >= 0; --i) {
        a[i + 1] = mul(a[i], mul(invf[i + 1], fact[i]));
    }
    a[0] = 0;
    return a;
}

vector<int> ln(vector<int> a, int n) {
    auto res = integ(der(a) * inv(a, n));
    res.resize(n);
    return res;
}

vector<int> exp(vector<int> f, int n) {
    vector<int> g = {1};
    int m = 1;
    static vector<int> f1;
    while (m < n) {
        f1.resize(2 * m);
        fill(f1.begin(), f1.end(), 0);
        for (int i = 0; i < (int)f.size() && i < 2 * m; ++i) {
            f1[i] = f[i];
        }
        g = (f1 - ln(g, 2 * m) + vector<int>(1, 1)) * g;
        g.resize(2 * m);
        m *= 2;
    }
    g.resize(n);
    return g;
}

void solve() {
    int n, k;
    cin >> n >> k;
    vector<int> a(n);
    for (int i = 1; i < n; ++i) {
        cin >> a[i];
    }
    vector<int> eia = exp(integ(a), max(n, k + 1));
    vector<int> cur(n + k);
    for (int i = 0; i <= k; ++i) {
        cur[i + n - 1] = eia[i];
    }
    vector<int> der_cur(n);
    for (int i = 0; i < n; ++i) {
        der_cur[i] = mul(cur[i + k], mul(fact[i + k], invf[i]));
    }
    vector<int> ans = der_cur * inv(eia, n);
    for (int i = n - 1; i >= 0; --i) {
        cout << ans[i] << " ";
    }
    cout << "\n";
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);

    fact[0] = 1;
    for (int i = 1; i < MAXF; ++i) {
        fact[i] = mul(fact[i - 1], i);
    }
    invf[MAXF - 1] = pw(fact[MAXF - 1], MOD - 2);
    for (int i = MAXF - 1; i > 0; --i) {
        invf[i - 1] = mul(invf[i], i);
    }

    int tst;
    cin >> tst;
    while (tst--) {
        solve();
    }

    return 0;
}

詳細信息

Test #1:

score: 100
Accepted
time: 4749ms
memory: 43220kb

input:

14
3 2
1 2

3 1
1 2

7 10
1 1 4 5 1 4

2 1
998244352

18 32
1 0 1 0 1 0 0 0 0 1 1 1 0 0 0 0 1

188 19
633886818 153877981 415015507 40745200 269787796 274990221 297547338 934403707 463583160 490465672 641355195 897012511 641637182 821068661 614724038 55504516 717220803 796828809 578138752 516258420 ...

output:

5 0 2 
0 2 0 
475251424 113315999 791330691 478266847 175921200 46569600 4082400 
0 1 
290297689 111948457 905336170 325091865 481715174 560516169 711953201 909617930 834449213 230629315 299970170 870572449 496138561 512305244 580683156 556935218 282162750 458443581 
900977301 704879246 103685386 11...

result:

ok 14 lines