QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#446062#6513. Expression 3Wavelet#TL 3ms28064kbC++145.1kb2024-06-16 20:44:132024-06-16 20:44:13

Judging History

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

  • [2024-06-16 20:44:13]
  • 评测
  • 测评结果:TL
  • 用时:3ms
  • 内存:28064kb
  • [2024-06-16 20:44:13]
  • 提交

answer

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

const int MODT = 998244353;
const int g = 3;

int power(int a, int b, int MOD){
    int r = 1;
    while(b){
        if(b & 1) r = 1ll * r * a % MOD;
        b >>= 1,  a = 1ll * a * a % MOD;
    }
    return r;
}

namespace Hash {
    const int SIZ = 1999997;

    int H[SIZ], V[SIZ], W[SIZ], N[SIZ], t;
    int S[SIZ], s;

    void add(int h, int v){
        int u = h % SIZ;
        V[++ t] = h, W[t] = v, N[t] = H[u], H[u] = t;
        S[++ s] = u;
    }

    int find(int h){
        for(int p = H[h % SIZ];p;p = N[p]) if(V[p] == h)
            return W[p];
        
        return -1;
    }
}

void bsgs_init(){
    int m = sqrt(MODT + 1);

    int w = 1;
    for(int i = 0;i < m;++ i){
        Hash :: add(w, i);
        w = 1ll * w * g % MODT;
    }

    // cerr << w << endl;
}

int bsgs(int x){
    int m = sqrt(MODT + 1);

    int h = 1;
    int w = power(g, m, MODT);
    int y = power(x, MODT - 2, MODT);

    for(int i = 1;(i - 1) * m < MODT;++ i){
        h = 1ll * h * w % MODT;
        int f;
        if((f = Hash :: find(1ll * h * y % MODT)) != -1)
            return i * m - f;
    }
    return -1;
}

const int MAXN = 2e5 + 3;
int A[MAXN], I[MAXN]; char O[MAXN];

const int MOD1 = 985661441;
const int MOD2 = 998244353;
const int MOD3 = 1004535809;

namespace Poly {
    const int SIZ = (1 << 21);

    void NTT(int n, int Z[], int MOD){
        static int W[SIZ];
        int l = 1;
        W[0] = 0;
        while(n >>= 1){
            for(int i = 0, END = l - 1;i <= END;++ i)
                W[l ++] = W[i] << 1 | 1, W[i] <<= 1;
        }
        for(int i = 0;i <= l - 1;++ i)
            if(W[i] > i)
                swap(Z[i], Z[W[i]]);
        for(n = l >> 1, l = 1;n;n >>= 1, l <<= 1){
            int *S = Z, o = power(g, (MOD - 1) / l / 2, MOD);
            for(int i = 0;i < n;++ i){
                int s = 1;
                for(int j = 0;j < l;++ j){
                    int x = (S[j] + 1ll * s * S[j + l] % MOD      ) % MOD;
                    int y = (S[j] - 1ll * s * S[j + l] % MOD + MOD) % MOD;
                    S[j] = x, S[j + l] = y;
                    s = 1ll * s * o % MOD;
                }
                S += l << 1;
            }
        }
    }
    void INTT(int n, int Z[], int MOD){
        NTT(n, Z, MOD); reverse(Z + 1, Z + n);
        int o = power(n, MOD - 2, MOD);
        for(int i = 0;i < n;++ i)
            Z[i] = 1ll * Z[i] * o % MOD;
    }
}

const int MAXM = 1.2e6 + 3;

int P[MAXM], Q[MAXM];
int X[MAXM], Y[MAXM];

bool F[MAXN];

int A1[MAXN], B1[MAXN];
int A2[MAXN], B2[MAXN];
int A3[MAXN], B3[MAXN];

void mul(int l, int A[], int B[], int MOD){

    memcpy(A1, A, l * sizeof(int));
    memcpy(A2, A, l * sizeof(int));
    memcpy(A3, A, l * sizeof(int));
    memcpy(B1, B, l * sizeof(int));
    memcpy(B2, B, l * sizeof(int));
    memcpy(B3, B, l * sizeof(int));

    Poly :: NTT(l, A1, MOD1);
    Poly :: NTT(l, B1, MOD1);
    for(int i = 0;i < l;++ i)
        A1[i] = 1ll * A1[i] * B1[i] % MOD1;
    Poly :: INTT(l, A1, MOD1);

    Poly :: NTT(l, A2, MOD2);
    Poly :: NTT(l, B2, MOD2);
    for(int i = 0;i < l;++ i)
        A2[i] = 1ll * A2[i] * B2[i] % MOD2;
    Poly :: INTT(l, A2, MOD2);

    Poly :: NTT(l, A3, MOD3);
    Poly :: NTT(l, B3, MOD3);
    for(int i = 0;i < l;++ i)
        A3[i] = 1ll * A3[i] * B3[i] % MOD3;
    Poly :: INTT(l, A3, MOD3);

    for(int i = 0;i < l;++ i){
        int a1 = A1[i], a2 = A2[i], a3 = A3[i];

        long long p1 = 1ll * MOD2 * MOD3;
        long long p2 = 1ll * MOD1 * MOD3;
        long long p3 = 1ll * MOD1 * MOD2;

        int g1 = power(1ll * MOD2 * MOD3 % MOD1, MOD1 - 2, MOD1);
        int g2 = power(1ll * MOD1 * MOD3 % MOD2, MOD2 - 2, MOD2);
        int g3 = power(1ll * MOD1 * MOD2 % MOD3, MOD3 - 2, MOD3);

        __int128 gg = (__int128)a1 * p1 * g1 + (__int128)a2 * p2 * g2 + (__int128)a3 * p3 * g3;

        A[i] = gg % ((__int128)MOD1 * MOD2 * MOD3) % MOD;
    }
}

int main(){
    ios :: sync_with_stdio(false);
    cin.tie(nullptr);

    bsgs_init();

    int n;
    cin >> n;
    for(int i = 1;i <= n;++ i){
        cin >> A[i];
        I[i] = bsgs(i);
    }

    for(int i = 0;i <= n - 2;++ i){
        P[i] = I[i + 1];

        if(i == 0)
            Q[i] = bsgs(MODT - 1);
        else 
        if(i == 1)
            Q[i] = 0;
        else 
            Q[i] = I[i - 1];
    }

    for(int i = 1;i <= n - 1;++ i){
        cin >> O[i];

        if(O[i] == '+'){
            X[i + n - 1] = 1;
        } else {
            Y[i + n - 1] = 1;
            F[i + 2] = true;
        }
    }

    for(int i = 0;i <= n - 1;++ i){
        X[i] = 1;
    }

    int l = 1;
    while(l <= 3 * n)
        l <<= 1;
    
    mul(l, P, X, MODT - 1);
    mul(l, Q, Y, MODT - 1);

    int ans = 0;
    for(int i = 1;i <= n;++ i) if(!F[i]){
        int u = P[i + n - 2] + Q[i + n - 2];
        ans = (ans + 1ll * A[i] * power(g, u, MODT)) % MODT;
    }
    cout << ans << endl;
    return 0;
}

/*
5
1 2 3 4 5
+-+-

4
9 1 4 1
-+-
*/

详细

Test #1:

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

input:

4
9 1 4 1
-+-

output:

46

result:

ok 1 number(s): "46"

Test #2:

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

input:

5
1 2 3 4 5
+-+-

output:

998244313

result:

ok 1 number(s): "998244313"

Test #3:

score: -100
Time Limit Exceeded

input:

100000
664815434 205025136 871445392 797947979 379688564 336946672 231295524 401655676 526374414 670533644 156882283 372427821 700299596 166140732 677498490 44858761 185182210 559696133 813911251 842364231 681916958 114039865 222372111 784286397 437994571 152137641 650875922 613727135 209302742 5321...

output:


result: