QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#547982#8305. Acceleratorhaze#AC ✓1726ms164088kbC++2311.8kb2024-09-05 14:22:312024-09-05 14:22:32

Judging History

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

  • [2024-09-05 14:22:32]
  • 评测
  • 测评结果:AC
  • 用时:1726ms
  • 内存:164088kb
  • [2024-09-05 14:22:31]
  • 提交

answer

#include <cstdio>
#include <bits/stdc++.h>
#define int long long
const int maxn = 3e6 + 5, mod = 998244353;

template<typename T>
inline T max(const T &a, const T &b) {
    return a > b ? a : b;
}

template<typename T>
inline void swap(T &a, T &b) {
    T temp = a;
    a = b;
    b = temp;
}

struct IO {
    IO() {};
    char c;

    inline char gc() {
        static char buf[maxn], *p1 = buf, *p2 = buf;
        return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, maxn, stdin), p1 == p2) ? EOF : *p1++;
    }

    template<typename T>
    inline IO &operator>>(T &_) {
        _ = 0;
        bool f = 1;
        c = gc();
        while (c < '0' || c > '9') {
            if (c == '-') f = 0;
            c = gc();
        }
        while (c >= '0' && c <= '9') {
            _ = _ * 10 + c - 48;
            c = gc();
        }
        if (!f) _ = -_;
        return *this;
    }

    char buf[maxn];
    int p = 0;

    ~IO() { fwrite(buf, 1, p, stdout); }

    inline void pc(const char &c) {
        buf[p++] = c;
        if (p == maxn) fwrite(buf, 1, maxn, stdout), p = 0;
    }

    template<typename T>
    inline IO &operator<<(T x) {
        if (!x) {
            pc(48);
            return *this;
        }
        static int wt[41], len;
        len = 0;
        if (x < 0) {
            pc('-');
            x = -x;
        }
        for (; x; x /= 10) { wt[++len] = x % 10; }
        while (len) { pc(wt[len--] + 48); }
        return *this;
    }

    inline IO &operator<<(const char &c) {
        pc(c);
        return *this;
    }
} io;

int fastpow(int x, int y) {
    if (y == 0) return 1;
    int tmp = fastpow(x, y >> 1);
    return y & 1 ? 1ll * tmp * tmp % mod * x % mod : 1ll * tmp * tmp % mod;
}

inline int add(int x, int y) { return x + y >= mod ? x + y - mod : x + y; }

inline int sub(int x, int y) { return x - y < 0 ? x - y + mod : x - y; }

inline void copy(int *Alpha, int *Beta, int len) {
    //Alpha -> Beta
    for (int i = 0; i < len; i++) Alpha[i] = Beta[i];
}

namespace Poly {
    const int gate = 3, invg = fastpow(gate, mod - 2);
    int lim, lg, sing[maxn];
    int Gate[maxn], Invg[maxn];
    int inv[maxn];

    void init(int len) {
        lim = 1, lg = 0;
        while (lim < len) lim <<= 1, lg++;
        for (int i = 1; i < lim; i++) sing[i] = (sing[i >> 1] >> 1) | ((i & 1) << (lg - 1));
    }

    int Hacking_to_the() {
        for (int i = 1; i < maxn; i <<= 1)
            Gate[i] = fastpow(gate, (mod - 1) / (i << 1)), Invg[i] = fastpow(invg, (mod - 1) / (i << 1));
        // inv[1] = 1 ;for(int i=2;i<maxn;i++) inv[i] = (mod-1ll*(mod/i)*inv[mod%i]%mod) ;
        return 0;
    }

    int GATE = Hacking_to_the();

    void NTT(int *Steins, int type) {
        for (int i = 0; i < lim; i++) if (i < sing[i]) swap(Steins[i], Steins[sing[i]]);
        for (int len = 1; len < lim; len <<= 1) {
            int unit = type == 1 ? Gate[len] : Invg[len];
            for (int i = 0; i < lim; i += (len << 1)) {
                int w = 1;
                for (int k = 0; k < len; k++, w = 1ll * w * unit % mod) {
                    int x = Steins[i + k], y = 1ll * w * Steins[i + k + len] % mod;
                    Steins[i + k] = add(x, y), Steins[i + k + len] = sub(x, y);
                }
            }
        }
        if (type != 1) {
            int Okabe = fastpow(lim, mod - 2);
            for (int i = 0; i < lim; i++) Steins[i] = 1ll * Steins[i] * Okabe % mod;
        }
    }

    void convolution(int *Alpha, int la, int *Beta, int lb, int *Zeta) {
        init(la + lb - 1);
        for (int i = la; i < lim; i++) Alpha[i] = 0;
        for (int i = lb; i < lim; i++) Beta[i] = 0;
        NTT(Alpha, 1), NTT(Beta, 1);
        for (int i = 0; i < lim; i++) Zeta[i] = 1ll * Alpha[i] * Beta[i] % mod;
        return NTT(Zeta, -1);
    }

    int g[maxn];

    void get_inv(int *Alpha, int len, int *Beta) {
        //使用前清空Beta数组
        if (len == 1) {
            Beta[0] = fastpow(Alpha[0], mod - 2);
            return;
        }
        get_inv(Alpha, (len + 1) >> 1, Beta);
        init(len + len - 1);
        copy(g, Alpha, len);
        for (int i = len; i < lim; i++) g[i] = 0;
        NTT(Beta, 1), NTT(g, 1);
        for (int i = 0; i < lim; i++) Beta[i] = 1ll * Beta[i] * (mod + 2 - 1ll * Beta[i] * g[i] % mod) % mod;
        NTT(Beta, -1);
        for (int i = len; i < lim; i++) Beta[i] = 0;
    }

    const int inv2 = fastpow(2, mod - 2);
    int t[maxn];

    void get_sqrt(int *Alpha, int len, int *Beta) {
        //使用前清空Beta数组
        if (len == 1) {
            Beta[0] = 1;
            return;
        }
        get_sqrt(Alpha, (len + 1) >> 1, Beta);
        get_inv(Beta, len, t);
        init(len + len - 1);
        copy(g, Alpha, len);
        for (int i = len; i < lim; i++) g[i] = 0;
        convolution(g, len, t, len, g);
        for (int i = 0; i < lim; i++) Beta[i] = 1ll * inv2 * (Beta[i] + g[i]) % mod;
        for (int i = len; i < lim; i++) Beta[i] = 0;
        for (int i = 0; i < lim; i++) t[i] = 0;
    }

    void derivative(int *Alpha, int len, int *Beta) {
        for (int i = 1; i < len; i++) Beta[i - 1] = 1ll * i * Alpha[i] % mod;
        Beta[len - 1] = 0;
    }

    void integral(int *Alpha, int len, int *Beta) {
        for (int i = len - 1; i >= 1; i--) Beta[i] = 1ll * Alpha[i - 1] * inv[i];
        Beta[0] = 0;
    }

    int f1[maxn], f2[maxn];

    void get_ln(int *Alpha, int len, int *Beta) {
        memset(f2, 0, sizeof(f2));
        derivative(Alpha, len, f1), get_inv(Alpha, len, f2);
        convolution(f1, len, f2, len, Beta);
        return integral(Beta, len, Beta);
    }

    int e1[maxn], e2[maxn];

    void get_exp(int *Alpha, int len, int *Beta) {
        //使用前清空Beta数组
        if (len == 1) return void(Beta[0] = 1);
        get_exp(Alpha, (len + 1) >> 1, Beta);
        get_ln(Beta, len, e1);
        init(len + len - 1);
        for (int i = 0; i < len; i++) e2[i] = sub(Alpha[i], e1[i]);
        for (int i = len; i < lim; i++) e2[i] = 0;
        NTT(e2, 1), NTT(Beta, 1);
        for (int i = 0; i < lim; i++) Beta[i] = 1ll * Beta[i] * (e2[i] + 1) % mod;
        NTT(Beta, -1);
        for (int i = len; i < lim; i++) Beta[i] = 0;
        for (int i = 0; i < lim; i++) e1[i] = 0;
    }

    int g1[maxn], g2[maxn], g3[maxn];

    void division(int *Alpha, int la, int *Beta, int lb, int *Zeta, int *Gamma) {
        //Zeta's length requires 2la-lb
        if (la < lb) {
            for (int i = 0; i <= la - lb; i++) Zeta[i] = 0;
            for (int i = la; i < lb; i++) Gamma[i] = 0;
            return copy(Gamma, Alpha, la);
        }
        for (int i = 0; i < la; i++) g1[i] = Alpha[la - i - 1];
        for (int i = 0; i < lb; i++) g2[i] = Beta[lb - i - 1];
        for (int i = lb; i <= la - lb; i++) g2[i] = 0;
        lim = 1;
        while (lim <= (la - lb) << 1) lim <<= 1;
        for (int i = 0; i < lim; i++) g3[i] = 0;
        get_inv(g2, la - lb + 1, g3);
        convolution(g1, la, g3, la - lb + 1, Zeta);
        for (int i = 0; i < la - lb - i; i++) swap(Zeta[i], Zeta[la - lb - i]);
        for (int i = la - lb + 1; i < lim; i++) Zeta[i] = 0;
        copy(g1, Beta, lb);
        copy(g2, Zeta, la - lb + 1);
        convolution(g1, lb, g2, la - lb + 1, g1);
        for (int i = 0; i < lb; i++) Gamma[i] = sub(Alpha[i], g1[i]);
    }
}

namespace Multi_point {
    int *gate[maxn << 2];

    void init(int now, int l, int r, int *Alpha) {
        if (l == r) {
            gate[now] = new int[2];
            gate[now][0] = mod - Alpha[l], gate[now][1] = 1;
            return;
        }
        int mid = (l + r) >> 1, lim = 1;
        while (lim < r - l + 1 + 1) lim <<= 1;
        gate[now] = new int[lim];
        int *g1 = new int[lim], *g2 = new int[lim];
        init(now << 1, l, mid, Alpha), init(now << 1 | 1, mid + 1, r, Alpha);
        copy(g1, gate[now << 1], mid - l + 1 + 1);
        copy(g2, gate[now << 1 | 1], r - mid + 1);
        return Poly::convolution(g1, mid - l + 1 + 1, g2, r - mid + 1, gate[now]);
    }

    void evaluation(int now, int l, int r, int *Alpha, int *Beta, int *Zeta) {
        //Alpha->f(x),Beta->S{x}
        if (r - l + 1 <= 256) {
            for (int i = l; i <= r; i++) {
                int answer = 0;
                int base = 1;
                for (int j = 0; j <= r - l; j++, base = 1ll * base * Beta[i] % mod)
                    answer = (answer + 1ll * base * Alpha[j]) % mod;
                Zeta[i] = answer;
            }
            return;//Which makes it faster;
        }
        int mid = (l + r) >> 1, lim = 1;
        while (lim < r - l + 1 + 1) lim <<= 1;
        int *g1, *g2;
        g1 = new int[lim << 1], g2 = new int[lim];
        Poly::division(Alpha, r - l + 1, gate[now << 1], mid - l + 1 + 1, g1, g2);
        evaluation(now << 1, l, mid, g2, Beta, Zeta);
        Poly::division(Alpha, r - l + 1, gate[now << 1 | 1], r - mid + 1, g1, g2);
        evaluation(now << 1 | 1, mid + 1, r, g2, Beta, Zeta);
        delete[] g1, delete[] g2;
    }

    int g1[maxn], g2[maxn];

    void Evaluation(int *Alpha, int len, int *Beta, int n, int *Zeta) {
        init(1, 1, n, Beta);
        Poly::division(Alpha, len, gate[1], n + 1, g1, g2);
        return evaluation(1, 1, n, g2, Beta, Zeta);
    }

    int f1[maxn], f2[maxn], ell[maxn];
    int *Steins[maxn << 1], e1[maxn], e2[maxn], G1[maxn], G2[maxn];

    void interpolation(int now, int l, int r) {
        if (l == r) {
            Steins[now] = new int[1];
            return void(Steins[now][0] = ell[l]);
        }
        Steins[now] = new int[r - l + 1];
        int mid = (l + r) >> 1, lim = 1;
        interpolation(now << 1, l, mid), interpolation(now << 1 | 1, mid + 1, r);
        while (lim < (r - l + 1)) lim <<= 1;
        copy(G1, Steins[now << 1], mid - l + 1), copy(G2, Steins[now << 1 | 1], r - mid);
        copy(e1, gate[now << 1 | 1], r - mid + 1), copy(e2, gate[now << 1], mid - l + 1 + 1);
        Poly::convolution(e1, r - mid + 1, G1, mid - l + 1, e1);
        Poly::convolution(e2, mid - l + 1 + 1, G2, r - mid, e2);
        for (int i = 0; i <= r - l; i++) Steins[now][i] = (e1[i] + e2[i]) % mod;
    }

    void Interpolation(int *Alpha, int *Beta, int n, int *Zeta) {
        //Alpha->x,Beta->y
        init(1, 1, n, Alpha);
        copy(f1, gate[1], n + 1);
        Poly::derivative(f1, n + 1, f2);
        evaluation(1, 1, n, f2, Alpha, ell);
        for (int i = 1; i <= n; i++) ell[i] = 1ll * Beta[i] * fastpow(ell[i], mod - 2) % mod;
        interpolation(1, 1, n);
        return copy(Zeta, Steins[1], n);
    }
}

typedef long long ll;
int n;
ll Alpha[maxn], Beta[maxn], Zeta[maxn];
ll fr[maxn];
ll C(ll N1, ll M1){
    return fr[M1] * fr[N1 - M1] % mod * fastpow(fr[N1], mod - 2) % mod;
}
void solve() {
    scanf("%lld", &n);
    ll K = 1;
    for (int i = 1; i <= n; i++)
        scanf("%lld", &Alpha[i]), Beta[i] = 0, K *= Alpha[i], K %= mod;
    Alpha[++ n] = 0, Beta[n] = K;
    Multi_point::Interpolation(Alpha, Beta, n, Zeta);
    ll ans = 0, inv = fastpow(Zeta[n - 1], mod - 2);
    for (int i = 0; i < n - 1; i++){
        if(((i ^ n) & 1))ans += C(n - 1, i) * Zeta[i] % mod;
        else ans -= C(n - 1, i) * Zeta[i] % mod;
        ans %= mod;
    }
    ans = (ans * inv) % mod;
    io << (ans + mod) % mod << '\n';
}

signed main() {
    int T;
    fr[0] = 1;
    for(int i =1 ; i < 100000 + 10; ++ i){
        fr[i] = fr[i - 1] * i % mod;
    }
    scanf("%lld", &T);
    while (T--) {
        solve();
    }
//    scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d%d",&Alpha[i],&Beta[i]);
//    Multi_point::Interpolation(Alpha,Beta,n,Zeta);
//    for(int i=0;i<n;i++) io << Zeta[i] << " \n"[i==n-1];
//    return 0;
}


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

详细

Test #1:

score: 100
Accepted
time: 3ms
memory: 53772kb

input:

3
3
1 2 3
1
10
4
5 5 5 5

output:

665496247
10
780

result:

ok 3 lines

Test #2:

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

input:

100
1
847297038
5
203751343 825662680 957256277 500052871 818834331
5
987146111 742744954 629579339 780044373 494679147
8
251614896 194569580 916578218 533049529 530535094 733501237 367273760 385341463
7
375252389 260364079 389447501 409464874 846572964 772775526 503458256
2
123436633 211941084
6
19...

output:

847297038
51970068
170556219
113431915
760262074
246542542
195147099
493093785
168144980
126946554
710105918
669760399
717542211
546162274
355117267
476319791
504479282
611041492
409057254
586259120
411524107
467323677
604713606
677086599
337208713
428207507
929439958
108098278
655034669
220455699
6...

result:

ok 100 lines

Test #3:

score: 0
Accepted
time: 13ms
memory: 55540kb

input:

100
34
426400575 9927300 909720899 954255675 767998905 83905549 11564853 733479914 519688252 588206942 292994501 808946771 354495122 756030286 580925234 595222682 950714227 281486657 916585766 73918645 344801620 269358971 823314063 624176199 663573632 222827631 43334235 771899654 651401397 286161985...

output:

407047195
969184260
707290913
588793971
161624956
900764379
946042111
525481567
323619066
559679400
702641543
774077417
72041789
230297993
843180691
511827230
391868728
132163026
337301045
628148033
958328653
291354147
301471681
130398071
507222983
737846714
753300919
174373074
657380065
424492703
8...

result:

ok 100 lines

Test #4:

score: 0
Accepted
time: 239ms
memory: 88896kb

input:

100
718
404314538 399059943 992580922 926005407 338582419 649174215 974473772 173983508 842966562 421761508 29390122 51320322 611981261 892915925 76490050 235705837 849990374 33308970 67066467 977102595 675867852 125129873 255787127 312018985 952054434 722094045 171206475 890973351 126578304 3894293...

output:

995895670
994710069
713279557
626113157
685298699
907804742
382977068
204900737
784029914
680667123
403672352
99600221
456001194
444900792
239883144
340277780
204991006
861302818
509148571
413682190
7764599
301884750
936011407
341104983
78171640
403819556
641759875
377501122
207128991
70300471
37527...

result:

ok 100 lines

Test #5:

score: 0
Accepted
time: 107ms
memory: 69104kb

input:

1
8852
816257371 319861135 553044271 273391499 11309408 53548475 289068275 1599437 411634506 987136158 664105085 160956635 487913416 362514958 559857483 193029215 643883605 898606968 522890545 923619097 395182091 392324487 336898192 775191603 206906215 853876583 959896034 34058934 708850658 39009214...

output:

922706515

result:

ok single line: '922706515'

Test #6:

score: 0
Accepted
time: 1726ms
memory: 164088kb

input:

1
100000
566231680 552288735 269188130 832541422 403127222 314561085 693183364 216515795 91683984 754348153 872058608 487774703 990409975 718741890 508226988 309131993 285659464 917930011 933970844 911199697 737428687 529296820 389084211 395195075 750526573 985616979 885567650 915693886 901620354 56...

output:

440511824

result:

ok single line: '440511824'

Extra Test:

score: 0
Extra Test Passed