QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#465924#8010. Hierarchies of Judgesucup-team052#AC ✓2716ms17948kbC++149.4kb2024-07-07 13:48:562024-07-07 13:48:57

Judging History

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

  • [2024-07-07 13:48:57]
  • 评测
  • 测评结果:AC
  • 用时:2716ms
  • 内存:17948kb
  • [2024-07-07 13:48:56]
  • 提交

answer

#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = a; i <= b; i++)
#define per(i, a, b) for (int i = a; i >= b; i--)
using namespace std;

typedef unsigned long long ull;
typedef pair <int, int> pii;
typedef long long ll;

template <typename _T>
inline void read(_T &f) {
    f = 0; _T fu = 1; char c = getchar();
    while (c < '0' || c > '9') { if (c == '-') { fu = -1; } c = getchar(); }
    while (c >= '0' && c <= '9') { f = (f << 3) + (f << 1) + (c & 15); c = getchar(); }
    f *= fu;
}

template <typename T>
void print(T x) {
    if (x < 0) putchar('-'), x = -x;
    if (x < 10) putchar(x + 48);
    else print(x / 10), putchar(x % 10 + 48);
}

template <typename T>
void print(T x, char t) {
    print(x); putchar(t);
}

const int md = 998244353;

inline int add(int x, int y) {
    if (x + y >= md) return x + y - md;
    return x + y;
}

inline void addx(int &x, int y) {
    x += y;
    if (x >= md) x -= md;
}

inline int sub(int x, int y) {
    if (x < y) return x - y + md;
    return x - y;
}

inline void subx(int &x, int y) {
    x -= y;
    if (x < 0) x += md;
}

inline int mul(int x, int y) { return 1ull * x * y % md; }

inline int fpow(int x, int y) {
    int ans = 1;
    while (y) {
        if (y & 1) ans = mul(ans, x);
        y >>= 1; x = mul(x, x);
    }
    return ans;
}

namespace Poly {
    vector <int> roots, rev;

    void getRevRoot(int base) {
        int n = 1 << base;
        if ((int)rev.size() == n) return;
        rev.resize(n);
        for (int i = 1; i < n; i++) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (base - 1));
        if ((int)roots.size() >= n) return;
        int pren = max(1, (int)roots.size());
        roots.resize(n);
        for (int mid = pren; mid < n; mid <<= 1) {
            int wn = fpow(3, (md - 1) / (mid << 1));
            roots[mid] = 1;
            for (int i = 1; i < mid; i++) roots[i + mid] = mul(roots[i + mid - 1], wn);
        }
    }

    void ntt(vector <int> &a, int base) {
        int n = 1 << base;
        for (int i = 0; i < n; i++) {
            if (i < rev[i]) {
                swap(a[i], a[rev[i]]);
            }
        }
        for (int mid = 1; mid < n; mid <<= 1) {
            for (int i = 0; i < n; i += (mid << 1)) {
                for (int j = 0; j < mid; j++) {
                    int x = a[i + j], y = mul(a[i + j + mid], roots[mid + j]);
                    a[i + j] = add(x, y); a[i + j + mid] = sub(x, y);
                }
            }
        }
    }

    vector <int> operator * (vector <int> a, vector <int> b) {
        if ((int)a.size() <= 64 && (int)b.size() <= 64) {
            vector <int> ans(a.size() + b.size() - 1, 0);
            for (int i = 0; i < (int)a.size(); i++) {
                for (int j = 0; j < (int)b.size(); j++) {
                    ans[i + j] = add(ans[i + j], mul(a[i], b[j]));
                }
            }
            return ans;
        }
        int n = (int)a.size() + (int)b.size() - 1, base = 0;
        while ((1 << base) < n) ++base;
        a.resize(1 << base); b.resize(1 << base);
        getRevRoot(base); ntt(a, base); ntt(b, base);
        for (int i = 0; i < (1 << base); i++) a[i] = mul(a[i], b[i]);
        reverse(a.begin() + 1, a.end()); ntt(a, base); a.resize(n);
        int inv = fpow(1 << base, md - 2);
        for (int i = 0; i < n; i++) a[i] = mul(a[i], inv);
        return a;
    }

    vector <int> tmp;

    vector <int> pmul(vector <int> a, vector <int> b, int n, int ntted = 0) {
        int base = 0;
        while ((1 << base) < n) ++base;
        getRevRoot(base);
        a.resize(1 << base); ntt(a, base);
        if (!ntted) b.resize(1 << base), ntt(b, base), tmp = b;
        for (int i = 0; i < (1 << base); i++) a[i] = mul(a[i], tmp[i]);
        ntt(a, base); reverse(a.begin() + 1, a.end()); a.resize(n);
        int inv = fpow(1 << base, md - 2);
        for (int i = 0; i < n; i++) a[i] = mul(a[i], inv);
        return a;
    }

    vector <int> polyInv(vector <int> a, int n) {
        a.resize(n);
        if (n == 1) {
            vector <int> ans(1, fpow(a[0], md - 2));
            return ans;
        }
        vector <int> f0 = polyInv(a, (n + 1) >> 1), ans = f0;
        vector <int> now = pmul(a, f0, n, 0);
        for (int i = 0; i < (int)f0.size(); i++) now[i] = 0;
        now = pmul(now, vector <int> (0), n, 1); ans.resize(n);
        for (int i = (int)f0.size(); i < n; i++) ans[i] = sub(0, now[i]);
        return ans;
    }

    vector <int> polyInv(vector <int> a) {
        return polyInv(a, (int)a.size());
    }

    vector <int> operator + (vector <int> a, vector <int> b) {
        if (a.size() < b.size()) a.resize(b.size());
        for (int i = 0; i < (int)b.size(); i++) a[i] = add(a[i], b[i]);
        return a;
    }

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

    vector <int> diff(vector <int> f) {
        int n = (int)f.size() - 1;
        for (int i = 0; i < n; i++) f[i] = mul(f[i + 1], i + 1);
        f.resize(n); return f;
    }

    vector <int> inte(vector <int> f) {
        int n = (int)f.size() + 1; f.resize(n);
        for (int i = n - 1; i >= 1; i--) f[i] = mul(f[i - 1], fpow(i, md - 2));
        f[0] = 0; return f;
    }

    vector <int> polyLn(vector <int> f) {
        int n = (int)f.size();
        f = inte(diff(f) * polyInv(f));
        f.resize(n); return f;
    }

    vector <int> polyExp(vector <int> f, int base) {
        int n = 1 << base; f.resize(n);
        if (n == 1) {
            vector <int> ans(1, 1);
            return ans;
        }
        vector <int> g0 = polyExp(f, base - 1), g(1, 1);
        g0.resize(n);
        g = g0 * (g - polyLn(g0) + f);
        return g;
    }

    vector <int> polyExp(vector <int> f) {
        int n = (int)f.size(), base = 0;
        while ((1 << base) < n) ++base;
        f = polyExp(f, base); f.resize(n);
        return f;
    }
}

using Poly::operator *;
using Poly::operator -;
using Poly::polyInv;
using Poly::polyExp;

const int N = 2e5 + 5;

vector <int> F, G;
int fac[N], invv[N];
int n;

int df[N], dfg[N];
int f[N], g[N], fg[N], ef[N], efg[N], gg[N], efg_gg[N];

void solve(int l, int r) {
    if (l == r) {
        if (!l) return;
        f[l] = add(fg[l], sub(ef[l - 1], efg_gg[l - 1]));
        g[l] = add(gg[l], sub(ef[l - 1], efg[l - 1]));
        df[l] = mul(f[l], l); dfg[l] = mul(fg[l], l);
        ef[l] = add(f[l], mul(ef[l], invv[l]));
        efg[l] = add(fg[l], mul(efg[l], invv[l]));
        efg_gg[l] = add(efg_gg[l], gg[l]);
        return;
    }
    int mid = (l + r) >> 1;
    solve(l, mid);
    auto upd = [&](int *f, int *g, int *res) {
        vector <int> f1(mid - l + 1), f2;
        for (int i = l; i <= mid; i++) f1[i - l] = f[i];
        if (l == 0) {
            f2.resize(mid - l + 1);
            for (int i = 0; i <= mid - l; i++) f2[i] = g[i];
        } else {
            f2.resize(r - l + 1);
            for (int i = 0; i <= r - l; i++) f2[i] = g[i];
        }
        // fprintf(stderr, "l = %d, mid = %d, r = %d\n", l, mid, r);
        f1 = f1 * f2; f1.resize(r - l + 1);
        for (int i = mid + 1; i <= r; i++) res[i] = add(res[i], f1[i - l]);
    };
    if (l == 0) {
        upd(f, g, fg);
        upd(g, g, gg);
        upd(df, ef, ef);
        upd(dfg, efg, efg);
        upd(gg, efg, efg_gg);
    } else {
        upd(f, g, fg); upd(g, f, fg);
        upd(g, g, gg); upd(g, g, gg);
        upd(df, ef, ef); upd(ef, df, ef);
        upd(dfg, efg, efg); upd(efg, dfg, efg);
        upd(gg, efg, efg_gg); upd(efg, gg, efg_gg);
    }
    solve(mid + 1, r);
}

int main() {
    read(n);
    for (int i = 1; i <= n; i++) invv[i] = fpow(i, md - 2);
    fac[0] = 1;
    for (int i = 1; i <= n; i++) fac[i] = mul(fac[i - 1], i);
    f[1] = 1; ef[0] = 1; efg[0] = 1;
    /*
    {
        F.resize(2); G.resize(2);
        F[1] = 1; G[1] = 0;
        for (int i = 2; i <= n; i++) {
            vector <int> a = polyInv(vector <int> {1} - G);
            vector <int> f = a * (polyExp(F) - polyExp(F * G) * G * G);
            vector <int> g = a * (polyExp(F) - polyExp(F * G));
            F.push_back(f[i - 1]); G.push_back(g[i - 1]);
            printf("%d : %d %d\n", i, mul(fac[i], F[i]), mul(fac[i], G[i]));
        }
        vector <int> EF = polyExp(F), EFG = polyExp(F * G), GG = G * G, EFGGG = EFG * GG;
        fprintf(stderr, "ef : ");
        for (int i = 0; i <= n; i++) fprintf(stderr, "%d ", EF[i]);
        fprintf(stderr, "\n");
        fprintf(stderr, "efg : ");
        for (int i = 0; i <= n; i++) fprintf(stderr, "%d ", EFG[i]);
        fprintf(stderr, "\n");
        fprintf(stderr, "gg : ");
        for (int i = 0; i <= n; i++) fprintf(stderr, "%d ", GG[i]);
        fprintf(stderr, "\n");
        fprintf(stderr, "efggg : ");
        for (int i = 0; i <= n; i++) fprintf(stderr, "%d ", EFGGG[i]);
        fprintf(stderr, "\n");
    }
    */
    solve(0, n);
    /*
    for (int i = 1; i <= n; i++) {
        fprintf(stderr, "f[%d] = %d, g[%d] = %d, ef[%d] = %d, efg[%d] = %d, gg[%d] = %d, efg_gg[%d] = %d\n", i, mul(fac[i], f[i]), i, mul(fac[i], g[i]), i, ef[i], i, efg[i], i, gg[i], i, efg_gg[i]);
    }
    */
    print(mul(fac[n], add(f[n], g[n])), '\n');
    return 0;
}

这程序好像有点Bug,我给组数据试试?

Details

Tip: Click on the bar to expand more detailed information

Test #1:

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

input:

1

output:

1

result:

ok 1 number(s): "1"

Test #2:

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

input:

3

output:

24

result:

ok 1 number(s): "24"

Test #3:

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

input:

5

output:

3190

result:

ok 1 number(s): "3190"

Test #4:

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

input:

100

output:

413875584

result:

ok 1 number(s): "413875584"

Test #5:

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

input:

1

output:

1

result:

ok 1 number(s): "1"

Test #6:

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

input:

2

output:

4

result:

ok 1 number(s): "4"

Test #7:

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

input:

3

output:

24

result:

ok 1 number(s): "24"

Test #8:

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

input:

4

output:

236

result:

ok 1 number(s): "236"

Test #9:

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

input:

5

output:

3190

result:

ok 1 number(s): "3190"

Test #10:

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

input:

6

output:

55182

result:

ok 1 number(s): "55182"

Test #11:

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

input:

7

output:

1165220

result:

ok 1 number(s): "1165220"

Test #12:

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

input:

8

output:

29013896

result:

ok 1 number(s): "29013896"

Test #13:

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

input:

9

output:

832517514

result:

ok 1 number(s): "832517514"

Test #14:

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

input:

10

output:

96547079

result:

ok 1 number(s): "96547079"

Test #15:

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

input:

11

output:

296100513

result:

ok 1 number(s): "296100513"

Test #16:

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

input:

12

output:

672446962

result:

ok 1 number(s): "672446962"

Test #17:

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

input:

13

output:

986909297

result:

ok 1 number(s): "986909297"

Test #18:

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

input:

14

output:

306542229

result:

ok 1 number(s): "306542229"

Test #19:

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

input:

15

output:

8548107

result:

ok 1 number(s): "8548107"

Test #20:

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

input:

16

output:

773960239

result:

ok 1 number(s): "773960239"

Test #21:

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

input:

17

output:

611627547

result:

ok 1 number(s): "611627547"

Test #22:

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

input:

18

output:

91793980

result:

ok 1 number(s): "91793980"

Test #23:

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

input:

19

output:

689202618

result:

ok 1 number(s): "689202618"

Test #24:

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

input:

20

output:

605957782

result:

ok 1 number(s): "605957782"

Test #25:

score: 0
Accepted
time: 57ms
memory: 12040kb

input:

10000

output:

713782215

result:

ok 1 number(s): "713782215"

Test #26:

score: 0
Accepted
time: 115ms
memory: 10200kb

input:

20000

output:

337916836

result:

ok 1 number(s): "337916836"

Test #27:

score: 0
Accepted
time: 256ms
memory: 10516kb

input:

30000

output:

580803285

result:

ok 1 number(s): "580803285"

Test #28:

score: 0
Accepted
time: 285ms
memory: 12772kb

input:

40000

output:

732660392

result:

ok 1 number(s): "732660392"

Test #29:

score: 0
Accepted
time: 520ms
memory: 11384kb

input:

50000

output:

660835595

result:

ok 1 number(s): "660835595"

Test #30:

score: 0
Accepted
time: 549ms
memory: 11824kb

input:

60000

output:

323452070

result:

ok 1 number(s): "323452070"

Test #31:

score: 0
Accepted
time: 626ms
memory: 12856kb

input:

70000

output:

307315915

result:

ok 1 number(s): "307315915"

Test #32:

score: 0
Accepted
time: 644ms
memory: 13112kb

input:

80000

output:

951757567

result:

ok 1 number(s): "951757567"

Test #33:

score: 0
Accepted
time: 1168ms
memory: 14516kb

input:

90000

output:

426123208

result:

ok 1 number(s): "426123208"

Test #34:

score: 0
Accepted
time: 1190ms
memory: 13424kb

input:

100000

output:

827418228

result:

ok 1 number(s): "827418228"

Test #35:

score: 0
Accepted
time: 1238ms
memory: 14528kb

input:

110000

output:

541614559

result:

ok 1 number(s): "541614559"

Test #36:

score: 0
Accepted
time: 1259ms
memory: 12692kb

input:

120000

output:

184688986

result:

ok 1 number(s): "184688986"

Test #37:

score: 0
Accepted
time: 1280ms
memory: 14016kb

input:

130000

output:

898089371

result:

ok 1 number(s): "898089371"

Test #38:

score: 0
Accepted
time: 1394ms
memory: 16196kb

input:

140000

output:

949540221

result:

ok 1 number(s): "949540221"

Test #39:

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

input:

150000

output:

767689851

result:

ok 1 number(s): "767689851"

Test #40:

score: 0
Accepted
time: 1446ms
memory: 16816kb

input:

160000

output:

553494563

result:

ok 1 number(s): "553494563"

Test #41:

score: 0
Accepted
time: 1467ms
memory: 16744kb

input:

170000

output:

270711750

result:

ok 1 number(s): "270711750"

Test #42:

score: 0
Accepted
time: 2674ms
memory: 17472kb

input:

180000

output:

108155689

result:

ok 1 number(s): "108155689"

Test #43:

score: 0
Accepted
time: 2685ms
memory: 16520kb

input:

190000

output:

327542856

result:

ok 1 number(s): "327542856"

Test #44:

score: 0
Accepted
time: 2716ms
memory: 16504kb

input:

200000

output:

236144151

result:

ok 1 number(s): "236144151"

Test #45:

score: 0
Accepted
time: 2704ms
memory: 17948kb

input:

198798

output:

16935264

result:

ok 1 number(s): "16935264"

Extra Test:

score: 0
Extra Test Passed