QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#601527#5065. Beautiful Stringgozonite#TL 1730ms386168kbC++145.2kb2024-09-30 04:03:132024-09-30 04:03:13

Judging History

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

  • [2024-09-30 04:03:13]
  • 评测
  • 测评结果:TL
  • 用时:1730ms
  • 内存:386168kb
  • [2024-09-30 04:03:13]
  • 提交

answer

#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <algorithm>
#include <climits>
#include <cstdlib>
#include <cstdio>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <bitset>
#include <deque>
#include <queue>
#include <tuple>
#include <cmath>
#include <cctype>
#include <stack>
#include <cassert>
#include <iomanip>
#include <random>
#include <chrono>
using namespace std;
using ll = long long;

int n;
string s;
int bcnt[5001][5001]={}, pcnt[5001][5001]={}, lcnt[5001][5001]={};
int lmatch[5001][5001]={};
ll hsh[5001][2], pwr[5001][2], ipwr[5001][2];
ll a[] = {31, 97}, P[] = {ll(1e9 + 7), ll(1e9 + 9)};
ll ainv[] = {-1, -1};

ll binpow(ll b, ll e, ll p) {
    ll bp[31];
    bp[0] = b;
    for (int i = 1; i < 31; i++) bp[i] = bp[i-1]*bp[i-1] % p;
    ll res = 1;
    for (int i = 0; i < 31; i++)
        if (e & (1<<i)) res = res * bp[i] % p;
    return res;
}

ll inv(ll x, ll p) {
    return binpow(x, p-2LL, p);
}

bool heq(int i, int j, int l) {
    // assert(j+l-1 <= n && i+l-1 <= n && i >= 1 && j >= 1);
    for (int k = 0; k < 2; k++) {
        ll jh = (hsh[j+l-1][k] - hsh[j-1][k]) * ipwr[j][k] % P[k]; jh = (jh + P[k]) % P[k];
        ll ih = (hsh[i+l-1][k] - hsh[i-1][k]) * ipwr[i][k] % P[k]; ih = (ih + P[k]) % P[k];
        if (jh != ih) return false;
    }
    return true;
}

void build_hash() {
    for (int i = 0; i < 2; i++) {
        hsh[0][i] = 0;
        for (int j = 1; j <= n; j++) hsh[j][i] = (hsh[j-1][i] + ll(s[j]-'0')*pwr[j][i]) % P[i];
    }
}

int main() {
    // freopen("B.in", "r", stdin);
    // freopen("B.out", "w", stdout);

    for (int i = 0; i < 2; i++) {
        pwr[0][i] = 1;
        for (int j = 1; j <= 5000; j++) pwr[j][i] = pwr[j-1][i]*a[i] % P[i];
        ainv[i] = inv(a[i], P[i]);
        // cout << "ainv: " << ainv << i << endl;
        // assert((a[i] * ainv[i]) % P[i] == 1);
        ipwr[0][i] = 1;
        for (int j = 1; j <= 5000; j++) {
            ipwr[j][i] = ipwr[j-1][i]*ainv[i] % P[i];
            // cout << "pwr, ipwr: " << pwr[j][i] << " " << ipwr[j][i] << endl;
            // assert((pwr[j][i]*ipwr[j][i])%P[i] == 1);
        }
    }

    // run TC on sample strings???

    int T; cin >> T;
    while (T--) {
        cin >> s; n = s.size(); s = " " + s;
        build_hash();
        // cout << "testing 2 5: " << heq(2, 5, 1) << endl;

        for (int i = 1; i <= n; i++) { // compute pcnt[i][-]
            bcnt[i][0] = lcnt[i][0] = pcnt[i][0] = 0;
            for (int l = 1; i+l-1 <= n && i-l >= 1; l++) {
                bcnt[i][l] = heq(i, i-l, l);
                pcnt[i][l] = pcnt[i][l-1] + bcnt[i][l];
                lcnt[i][l] = lcnt[i][l-1] + l*bcnt[i][l];
            }
        }

        // cout << "pcnt: " << endl;
        // for (int i = 1; i <= n; i++) {
        //     cout << i << ": ";
        //     for (int l = 1; i+l-1 <= n && i-l >= 1; l++) cout << pcnt[i][l] << " ";
        //     cout << endl;
        // } cout << endl;

        // cout << "bcnt: " << endl;
        // for (int i = 1; i <= n; i++) {
        //     cout << i << ": ";
        //     for (int l = 1; i+l-1 <= n && i-l >= 1; l++) cout << bcnt[i][l] << " ";
        //     cout << endl;
        // } cout << endl;

        // cout << "lcnt: " << endl;
        // for (int i = 1; i <= n; i++) {
        //     cout << i << ": ";
        //     for (int l = 1; i+l-1 <= n && i-l >= 1; l++) cout << lcnt[i][l] << " ";
        //     cout << endl;
        // } cout << endl;

        for (int i = 1; i <= n; i++) {
            for (int j = i+1; j <= n; j++) {
                int low = 0, hi = min(j-i-1, n-j+1); // subtract 1 for s_4
                while (low < hi) {
                    int mid = (low + hi+1)/2;
                    // cout << "testing: " << i << " " << j << " " << mid << " " << heq(i, j, mid) << endl;
                    if (heq(i, j, mid)) low = mid;
                    else hi = mid-1;
                }
                lmatch[i][j] = low;
            }
        }

        // rewrite of the above: don't need to binary search
        for (int j = n; j >= 1; j--) {
            for (int i = j-1; i >= 1; i--) {
                if (s[i] != s[j]) lmatch[i][j] = 0;
                else {
                    lmatch[i][j] = min(1, j-i-1); // max len = j-i-1
                    if (j < n) lmatch[i][j] = max(lmatch[i][j], min(1+lmatch[i+1][j+1], j-i-1));
                }
            }
        }

        // cout << "checking lmatch: " << endl;
        // for (int i = 1; i <= n; i++) {
        //     for (int j = 1; j <= n; j++) {
        //         cout << lmatch[i][j] << " ";
        //     }
        //     cout << endl;
        // } cout << endl;

        ll ans = 0;
        for (int i = 1; i <= n; i++) {
            for (int j = i+1; j <= n; j++) {
                int lm = lmatch[i][j];
                int lmp = min(lm, i-1);
                ans += lm*pcnt[i][lmp] - lcnt[i][lmp];
                // cout << "adding: " << i << " " << j << " - " << lm << " " << pcnt[i][lm] << " " << lcnt[i][lm] << " " << ans << endl;
            }
        }
        cout << ans << endl;
    }
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

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

input:

2
114514
0000000

output:

1
3

result:

ok 2 number(s): "1 3"

Test #2:

score: 0
Accepted
time: 1730ms
memory: 386168kb

input:

11
79380
2483905227
37902399703986576270
39991723655814713848046032694137883815354365954917
5541883522667841718787744915558298207485830622522715211018760095628594390563630840464643840093757297
56530485554219245862513973750218715585679416120445975390556326891488719311495909340757506478400624741858999...

output:

0
0
0
2
4
20
119
113
1086
2128
15166

result:

ok 11 numbers

Test #3:

score: 0
Accepted
time: 92ms
memory: 26260kb

input:

50
11111111111111111111111111111111111111121111111111111111111111111111111111111112111111111121111111111211111121211121111111111111111111111111111211121111111111111111111111111111111111111111111111111112
111111111111111111111111111111111111111111111121111121111111111111111111111111111111111111111111...

output:

779344
799116
716078
723215
1197647
403357
652134
625671
414294
942493
390998
793444
612061
507395
473508
836065
461623
374925
539333
592574
676408
610940
463761
490048
995917
595830
424894
332669
596834
655095
521489
1032050
697420
752056
406316
360973
1180943
948628
478572
1026603
711224
429752
49...

result:

ok 50 numbers

Test #4:

score: 0
Accepted
time: 67ms
memory: 26476kb

input:

50
11211121122222111222111111222112111221112111121112221111111121211111212211212122112212221221112112221221112211211112121222112221211122112211112111112112211121222111222212211121111111112111112121111122
112112121211212111212221221222211211121212221111112122121211112221221121121112111221211112122121...

output:

7499
6375
7041
7889
6622
6804
8695
8795
7018
8387
8910
8019
8223
8820
7324
7144
8035
9941
7073
7373
7427
7280
6946
8204
7931
6769
7050
9268
7682
8232
7797
7356
7012
8967
7469
6869
11728
6562
7604
8840
7885
8658
7006
8156
10694
6716
6121
7499
7456
7981

result:

ok 50 numbers

Test #5:

score: -100
Time Limit Exceeded

input:

15
111111111111111111111111111111111111111111111111111111111111121111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111211111111111111111111111111111111111111111111111...

output:

6611556286
8447635347
4351265656
8244172287
6847075843
5064323828
5818821992
5187397748
6202849391

result: