QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#547973#8305. Acceleratorhaze#WA 249ms44504kbC++2311.9kb2024-09-05 14:16:372024-09-05 14:16:37

Judging History

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

  • [2024-09-05 14:16:37]
  • 评测
  • 测评结果:WA
  • 用时:249ms
  • 内存:44504kb
  • [2024-09-05 14:16:37]
  • 提交

answer

#include <cstdio>
#include <bits/stdc++.h>

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);
    }
}

int n;
int Alpha[maxn], Beta[maxn], Zeta[maxn];
typedef long long ll;
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("%d", &n);
    ll K = 1;
    for (int i = 1; i <= n; i++) scanf("%d", &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);
//    std::cerr << Zeta[n - 1] << ' ';
    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;
//        std::cerr << Zeta[i] << ' ';
    }
//    std::cerr << std::endl;
    ans = (ans * inv) % mod;
    io << (ans + mod) % mod << '\n';
}

int main() {
    int T;
    fr[0] = 1;
    for(int i =1 ; i < 100000 + 10; ++ i){
        fr[i] = fr[i - 1] * i % mod;
    }
    scanf("%d", &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;
}


Details

Tip: Click on the bar to expand more detailed information

Test #1:

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

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: 4ms
memory: 24824kb

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: 15ms
memory: 24224kb

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: -100
Wrong Answer
time: 249ms
memory: 44504kb

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
603994110
403819556
641759875
377501122
207128991
70300471
3752...

result:

wrong answer 25th lines differ - expected: '78171640', found: '603994110'