QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#504730#9111. Zayin and StringWorldFinalEscaped#WA 421ms67944kbC++145.2kb2024-08-04 15:26:172024-08-04 15:26:17

Judging History

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

  • [2024-08-04 15:26:17]
  • 评测
  • 测评结果:WA
  • 用时:421ms
  • 内存:67944kb
  • [2024-08-04 15:26:17]
  • 提交

answer

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

#define ll long long

const int N = 2005;
const int M = 4005;
const double eps = 1e-10;
const double inf = 1e14;
const int mod = 998244353;

inline int qpow(int a, int b = mod - 2) {
    int res = 1;
    while (b) {
        if (b & 1) res = 1ll * res * a % mod;
        a = 1ll * a * a % mod;
        b >>= 1; 
    }
    return res; 
}

char a[N], b[M];
int n, K;

vector<int> adj[M];
int fail[M];
int ch[M][26], actot;
ll val[M];

void dfs0(int u) {
    for (auto v: adj[u]) {
        val[v] += val[u];
        dfs0(v);
    }
}
void ac_build() {
    queue<int> q;
    for (int i = 0; i < 26; i++)
        if (ch[0][i])
            q.push(ch[0][i]), fail[ch[0][i]] = 0;
    while (!q.empty()) {
        int u = q.front(); q.pop();
        for (int i = 0; i < 26; i++) {
            int &go = ch[u][i];
            if (go) {
                fail[go] = ch[fail[u]][i];
                q.push(go);
            } else {
                go = ch[fail[u]][i];
            }
        }
    }
    for (int i = 1; i <= actot; i++) {
        adj[fail[i]].push_back(i);
    }
    dfs0(0);
}

// f[i][j]: a[1...i], ac node j
double f[N][M], g[N][M];
inline void ckmax(double &x, double y) {
    if (x < y) x = y;
}
inline bool check(double ANS) {
    f[0][0] = 0, g[0][0] = -inf;
    for (int j = 1; j <= actot; j++) {
        f[0][j] = g[0][j] = -inf;
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j <= actot; j++) {
            f[i][j] = -inf, g[i][j] = -inf;
        }
        for (int j = 0; j <= actot; j++) {
            // not choose a[i]
            ckmax(f[i][j], f[i - 1][j]);
            ckmax(g[i][j], g[i - 1][j]);
            // choose a[i]
            int trans = ch[j][a[i] - 'a'];
            ckmax(g[i][trans], max(f[i - 1][j], g[i - 1][j]) + val[trans] - ANS);
        }
//        for (int j = 0; j <= actot; j++) {
//            printf("f[%d][%d] = %.10f\n", i, j, f[i][j]);
//            printf("g[%d][%d] = %.10f\n", i, j, g[i][j]);
//        }
    }
    double t = *max_element(g[n], g[n] + actot + 1);
    return t >= -eps;
}

pair<int, int> where[N][M];
void check2(double ANS) {
    for (int i = 0; i <= n; i++) {
        for (int j = 0; j <= actot; j++) {
            where[i][j] = {-1, -1};
        }
    }

    f[0][0] = 0, g[0][0] = -inf;
    for (int j = 1; j <= actot; j++) {
        f[0][j] = g[0][j] = -inf;
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j <= actot; j++) {
            f[i][j] = -inf, g[i][j] = -inf;
        }
        for (int j = 0; j <= actot; j++) {
            // not choose a[i]
            ckmax(f[i][j], f[i - 1][j]);
            if (g[i][j] < g[i - 1][j])
                g[i][j] = g[i - 1][j], where[i][j] = {i - 1, j};
            // choose a[i]
            int trans = ch[j][a[i] - 'a'];
            if (g[i][trans] < f[i - 1][j] + val[trans] - ANS)
                g[i][trans] = f[i - 1][j] + val[trans] - ANS, where[i][trans] = {i - 1, -1};
            if (g[i][trans] < g[i - 1][j] + val[trans] - ANS)
                g[i][trans] = g[i - 1][j] + val[trans] - ANS, where[i][trans] = {i - 1, j};
        }
    }
    int I = n, J = max_element(g[n], g[n] + actot + 1) - g[n];
    vector<int> pos;
    while (J != -1) {
        if (where[I][J].second == -1) {
            pos.push_back(I);
            break;
        }
        if (where[I][J].second != J)
            pos.push_back(I);
        int i = where[I][J].first, j = where[I][J].second;
        I = i, J = j;
    }
    reverse(pos.begin(), pos.end());
    
//    cout << "ways = ";
//    for (auto it: pos) {
//        cout << it << ' ';
//    }
//    cout << '\n';
    
    int cur = 0;
    ll vals = 0;
    for (auto p: pos) {
        cur = ch[cur][a[p] - 'a'];
        vals += val[cur];
    }
//    printf("vals = %lld\n", vals);
     
    printf("%lld\n", vals % mod * qpow(pos.size()) % mod);
}

void sc() {
    while (actot >= 0) {
        memset(ch[actot], 0, sizeof(ch[actot]));
        fail[actot] = 0;
        val[actot] = 0;
        adj[actot].clear();
        actot--;
    }
    actot = 0;
    
    scanf("%d%d", &n, &K);
    scanf("%s", a + 1);
    while (K--) {
        scanf("%s", b + 1);
        int cur = 0;
        for (int i = 1; b[i] != '\0'; i++) {
            int &go = ch[cur][b[i] - 'a'];
            if (!go) go = ++actot;
            cur = go;
        }
        int _; scanf("%d", &_);
        val[cur] += _;
    }
    ac_build();
    
//    for (double t = -10; t <= 10; t += 1.0) {
//        printf("check(%d) = %d\n", t, check(t));
//    }
    
    double L = -1.5e8, R = 1.5e8;
    for (int times = 0; times <= 60; times++) { 
        double MID;
        if (fabs(R - L) > 1) MID = (L + R) / 2.0;
        else MID = sqrt(L * R);
        if (check(MID)) L = MID;
        else R = MID;
    }
//    printf("%.10f\n", L);
    check2(L);
}

int main() {
    int T; scanf("%d", &T);
    while (T--) sc();
    return 0;
}

/*
3
17 3
woyaoakccpcxiamen
ak 5
ccpc 6
xiamen 8
33 3
niweishenmezhengtianxunlianbuliwo
wo 3
se 1
zayin 7
39 2
programmingcontestandmewhichisimportant
me 11
gg 2
*/

/*
1
5 3
aaaaa
a 5
aa 4
aaaaa 100 
*/

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Wrong Answer
time: 421ms
memory: 67944kb

input:

80
4 7
ggeg
g 92946
d 65678
gg 50828
wrj 93954
gge 53780
a 94179
geg 40837
5 6
hiiii
ii 67984
foh 69185
hi 88153
pj 39431
i 32219
wfmve 96834
8 12
wvxxvwww
xw 1522
rzl 16262
wx 77596
v 69622
vw 82225
nykkmkv 19236
xv 83470
o 16781
w 2405
m 98319
ww 13889
qggbvty 16331
8 14
jjjiiijh
i 96670
z 74397
i...

output:

118360
73525
249640519
136709
665548146
81272
61572
67112
73114
748779217
88888
665557674
74929
665552405
499139737
665543594
332830174
60785
499200076
63646
103574
101389
432700990
332787384
133436
89874
94158
499215461
665540622
41750
782592345
96189
499208480
94537
83443
111657
665560098
21918
70...

result:

wrong answer 1st lines differ - expected: '332874949', found: '118360'