QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#504761#9111. Zayin and StringWorldFinalEscaped#WA 557ms47652kbC++144.2kb2024-08-04 15:41:592024-08-04 15:41:59

Judging History

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

  • [2024-08-04 15:41:59]
  • 评测
  • 测评结果:WA
  • 用时:557ms
  • 内存:47652kb
  • [2024-08-04 15:41:59]
  • 提交

answer

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

#define ll long long

const int N = 2005;
const int M = 4005;
const ll inf = 1e18;
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);
}

struct Foo {
    ll a, b; 
};
 
// f[i][j]: a[1...i], ac node j
ll f[N][M], g[N][M];
inline void ckmax(ll &x, ll y) {
    if (x < y) x = y;
}
inline ll check(Foo cur) {
    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] * cur.b - cur.a);
        }
//        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]);
//        }
    }
    ll t = *max_element(g[n], g[n] + actot + 1);
    return t; 
}

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));
//    }
    
    Foo L = {0, 1}, R = {1, 0}, ans; 
    int times = 20; 
    while (times--) {
        Foo MID = {L.a + R.a, L.b + R.b};
        ll p = check(MID);
//        printf("check %lld/%lld, p = %lld\n", mid.a, mid.b, p); 
        if (p == 0) {
            ans = MID;
            break; 
        } 
        if (p > 0) {
            ll l = 1, r = (1000000000 - L.a) / R.a;
            while (l < r) {
                int mid = l + r + 1 >> 1;
                Foo go = {L.a + mid * R.a, L.b + mid * R.b};
                if (check(go) >= 0) l = mid;
                else r = mid - 1; 
            } 
            L = {L.a + l * R.a, L.b + l * R.b}; 
        } else {
            ll l = 1, r = (1000000000 - R.a) / L.a;
            while (l < r) {
                int mid = l + r + 1 >> 1;
                Foo go = {R.a + mid * L.a, R.b + mid * L.b};
                if (check(go) < 0) l = mid;
                else r = mid - 1;
            } 
            R = {R.a + l * L.a, R.b + l * L.b};
        } 
    }
//    printf("ans = (%lld, %lld)\n", ans.a, ans.b); 
    printf("%lld\n", ans.a % mod * qpow(ans.b) % mod); 
}

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 
*/

详细

Test #1:

score: 0
Wrong Answer
time: 557ms
memory: 47652kb

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:

332874949
599030808
905939042
332898173
650366050
621047265
975220872
341938033
499196918
748779217
860751285
993621743
428267448
88523066
499139737
359147404
332830174
663415342
748771076
114174101
758798181
559688017
432700990
332787384
118190446
15049207
699354713
499215461
898048664
121771756
38...

result:

wrong answer 3rd lines differ - expected: '249640519', found: '905939042'