QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#278928#7876. Cyclic SubstringsfickleTL 873ms519844kbC++174.5kb2023-12-07 23:03:152023-12-07 23:03:16

Judging History

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

  • [2023-12-07 23:03:16]
  • 评测
  • 测评结果:TL
  • 用时:873ms
  • 内存:519844kb
  • [2023-12-07 23:03:15]
  • 提交

answer

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

#define fi first
#define se second
#define pb push_back
#define Mp make_pair
#define SZ(x) (int((x).size()))

typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;

constexpr int P1 = 998244353, P2 = 1e9 + 7, b1 = 231, b2 = 13131, N = 20000100;
int pw[N]; multiset<pii> st[6000100];

void solve() {
    int n; string s;
    cin >> n >> s;
    s = ' ' + s + s + s;
    
    pw[0] = 1;
    // pw[0] = Mp(1, 1);
    for(int i = 1; i < N; i++) {
        pw[i] = 1ll * pw[i - 1] * b1 % P1;
        // pw[i] = Mp( 1ll * pw[i - 1].fi * b1 % P1,
        //             1ll * pw[i - 1].se * b2 % P2);
    }
    vector<int> hsh; hsh.pb(0);
    auto push = [&](vector<int> &h, char ch) {
        auto a = h.back();
        hsh.pb((1ll * a * b1 + ch) % P1);
        // auto [a, b] = h.back();
        // hsh.pb(Mp(  (1ll * a * b1 + ch) % P1,
        //             (1ll * b * b2 + ch) % P2));
    };
    auto get = [&](vector<int> &h, int l, int r) -> int {
        auto L = h[l - 1], R = h[r];
        int len = r - l + 1;
        return (R - 1ll * L * pw[len] % P1 + P1) % P1;
        // return Mp(  (R.fi - 1ll * L.fi * pw[len].fi % P1 + P1) % P1,
        //             (R.se - 1ll * L.se * pw[len].se % P2 + P2) % P2);
    };

    string t = "-$";
    for(int i = 1; i <= 3 * n; i++) {
        t += s[i];
        t += '#';
    }
    t.pop_back(), t += "@";
    for(int i = 1; i < SZ(t); i++) {
        push(hsh, t[i]);
    }

    // cout << "f" << endl;
    vi r(4 * n + 2), fr(4 * n + 2), frlen(4 * n + 2);
    for(int i = 1, rmx = 0, center = 0; i <= 4 * n; i++) {
        if(i <= rmx) {
            r[i] = min(r[2 * center - i], rmx - i + 1);
            if(2 * center - i >= 2 * n + 1)
                fr[i] = 2 * center - i, frlen[i] = r[i];
        }
        while(i - r[i] > 0 && i + r[i] < SZ(t) && t[i - r[i]] == t[i + r[i]]) r[i]++;
        if(i + r[i] - 1 > rmx) rmx = i + r[i] - 1, center = i;
    }
    // cout << "f" << endl;
    // for(int i = 2 * n + 1; i <= 4 * n; i++) {
    //     cout << fr[i] << ' ' << frlen[i] << endl;
    // }
// t = -$0#1#0#1#0#_0#1#0#1#0_20_#0#1#0#1#0@
    vi cnt(4 * n + 2);
    map<pair<int, int>, int> mp;
    for(int i = 4 * n; i >= 2 * n + 1; i--) {
        cnt[i]++;
        int id = i - 2 * n;
        if(i & 1) { // even length
            while(r[i] > frlen[i]) {
                while(SZ(st[id]) && -st[id].begin()->fi == r[i]) {
                    cnt[i] += st[id].begin()->se;
                    st[id].erase(st[id].begin());
                }
                if(r[i] % 2 == 0 && r[i] <= n) {
                    auto h = get(hsh, i - r[i] + 1, i + r[i] - 1);
                    mp[Mp(h, r[i])] += cnt[i];
                    // cout << i - r[i] + 1 << ' ' << i + r[i] - 1 << ' ' << r[i] << ' ' << cnt[i] << "    " << h.fi << ' ' << h.se << endl;
                }
                r[i]--;
            }
        } else {
            while(r[i] > frlen[i]) {
                while(SZ(st[id]) && -st[id].begin()->fi == r[i]) {
                    cnt[i] += st[id].begin()->se;
                    st[id].erase(st[id].begin());
                }
                if(r[i] % 2 != 0 && r[i] <= n) {
                    auto h = get(hsh, i - r[i] + 1, i + r[i] - 1);
                    // cout << i - r[i] + 1 << ' ' << i + r[i] - 1 << ' ' << r[i] << ' ' << cnt[i] << "    " << h.fi << ' ' << h.se << endl;
                    mp[Mp(h, r[i])] += cnt[i];
                }
                r[i]--;
            }
        }
        auto merge = [&](multiset<pii> &st1, multiset<pii> &st2) {
            if(SZ(st1) < SZ(st2)) swap(st1, st2);
            for(auto o : st2) st1.insert(o);
        };
        if(fr[i]) {
            // assert(0 <= fr[i] - 2 * n && fr[i] - 2 * n < 2000100);
            // assert(0 <= i - 2 * n && i - 2 * n < 2000100);
            merge(st[fr[i] - 2 * n], st[id]);
            st[fr[i] - 2 * n].insert(Mp(-frlen[i], cnt[i]));
        }
    }
    // cout << "f" << endl;

    ll ans = 0;
    for(auto [p, c] : mp) {
        int len = p.se;
        // cout << len << ' ' << c << '\n';
        (ans += 1ll * c * c * len) %= P1;
    }

    cout << ans << '\n';
}
signed main() {
    // freopen("data.in", "r", stdin);
    atexit([]{cerr << 1. * clock() / CLOCKS_PER_SEC << "s\n";});
    ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int t = 1;
    // cin >> t;
    while(t--) solve();
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 102ms
memory: 363348kb

input:

5
01010

output:

39

result:

ok 1 number(s): "39"

Test #2:

score: 0
Accepted
time: 118ms
memory: 363356kb

input:

8
66776677

output:

192

result:

ok 1 number(s): "192"

Test #3:

score: 0
Accepted
time: 125ms
memory: 363524kb

input:

1
1

output:

1

result:

ok 1 number(s): "1"

Test #4:

score: 0
Accepted
time: 115ms
memory: 363356kb

input:

2
22

output:

12

result:

ok 1 number(s): "12"

Test #5:

score: 0
Accepted
time: 108ms
memory: 363360kb

input:

2
21

output:

2

result:

ok 1 number(s): "2"

Test #6:

score: 0
Accepted
time: 139ms
memory: 363348kb

input:

3
233

output:

10

result:

ok 1 number(s): "10"

Test #7:

score: 0
Accepted
time: 96ms
memory: 363352kb

input:

3
666

output:

54

result:

ok 1 number(s): "54"

Test #8:

score: 0
Accepted
time: 873ms
memory: 519844kb

input:

1000000
3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333...

output:

496166704

result:

ok 1 number(s): "496166704"

Test #9:

score: -100
Time Limit Exceeded

input:

3000000
2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222...

output:


result: