QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#273520#7876. Cyclic Substringsucup-team1516#AC ✓1836ms617944kbC++208.2kb2023-12-03 00:45:202023-12-03 00:45:20

Judging History

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

  • [2023-12-03 00:45:20]
  • 评测
  • 测评结果:AC
  • 用时:1836ms
  • 内存:617944kb
  • [2023-12-03 00:45:20]
  • 提交

answer

#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#define ll long long
#define ull unsigned long long
#define db double
#define pii pair<int,int>
#define pli pair<ll,int>
#define pil pair<int,ll>
#define pll pair<ll,ll>
#define ti3 tuple<int,int,int>
#define int128 __int128_t
#define pii128 pair<int128,int128>
const int inf = 1 << 30;
const ll linf = 1e18;
const ll mod = 998244353;
const db EPS = 1e-10;
const db pi = acos(-1);
template<class T> bool chmin(T& x, T y){
    if(x > y) {
        x = y;
        return true;
    } else return false;
}
template<class T> bool chmax(T& x, T y){
    if(x < y) {
        x = y;
        return true;
    } else return false;
}

// overload macro
#define CAT( A, B ) A ## B
#define SELECT( NAME, NUM ) CAT( NAME, NUM )

#define GET_COUNT( _1, _2, _3, _4, _5, _6 /* ad nauseam */, COUNT, ... ) COUNT
#define VA_SIZE( ... ) GET_COUNT( __VA_ARGS__, 6, 5, 4, 3, 2, 1 )

#define VA_SELECT( NAME, ... ) SELECT( NAME, VA_SIZE(__VA_ARGS__) )(__VA_ARGS__)

// rep(overload)
#define rep( ... ) VA_SELECT(rep, __VA_ARGS__)
#define rep2(i, n) for (int i = 0; i < int(n); i++)
#define rep3(i, a, b) for (int i = a; i < int(b); i++)
#define rep4(i, a, b, c) for (int i = a; i < int(b); i += c)

// repll(overload)
#define repll( ... ) VA_SELECT(repll, __VA_ARGS__)
#define repll2(i, n) for (ll i = 0; i < (ll)(n); i++)
#define repll3(i, a, b) for (ll i = a; i < (ll)(b); i++)
#define repll4(i, a, b, c) for (ll i = a; i < (ll)(b); i += c)

// rrep(overload)
#define rrep( ... ) VA_SELECT(rrep, __VA_ARGS__)    
#define rrep2(i, n) for (int i = n - 1; i >= 0; i--)
#define rrep3(i, a, b) for (int i = b - 1; i >= a; i--)
#define rrep4(i, a, b, c) for (int i = b - 1; i >= a; i -= c)

// rrepll(overload)
#define rrepll( ... ) VA_SELECT(rrepll, __VA_ARGS__)
#define rrepll2(i, n) for (ll i = (ll)(n) - 1; i >= 0ll; i--)
#define rrepll3(i, a, b) for (ll i = b - 1; i >= (ll)(a); i--)
#define rrepll4(i, a, b, c) for (ll i = b - 1; i >= (ll)(a); i -= c)

// for_earh
#define fore(e, v) for (auto&& e : v)

// vector
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()

template<long long mod>
struct modint{
    long long num;

    constexpr modint(long long x = 0) : num((x + mod) % mod) {}

    constexpr modint &operator += (const modint& rhs){
        num = (num + rhs.num) % mod;
        return *this;
    }
    constexpr modint &operator -= (const modint& rhs){
        num  -= rhs.num;
        while(num < 0) num += mod;
        num %= mod;
        return *this;
    }
    constexpr modint &operator *= (const modint& rhs){
        num = num * rhs.num % mod;
        return *this;
    }
    constexpr modint &operator /= (modint rhs){
        int exp = mod - 2;
        while(exp > 0){
            if(exp % 2){
                *this *= rhs;
            }
            rhs *= rhs;
            exp /= 2;
        }
        return *this;
    }

    constexpr modint operator ++ (){
        num = (num + 1) % mod;
        return *this;
    }
    constexpr modint operator ++ (int n){
        (void)n;
        modint tmp = *this;
        ++(*this);
        return tmp;
    }
    constexpr modint operator -- (){
        num = (num + mod - 1) % mod;
        return *this;
    }
    constexpr modint operator -- (int n){
        (void)n;
        const modint tmp = *this;
        --(*this);
        return tmp;
    }

    void modpow(ll y){
        modint tmp = (*this);
        (*this) = 1;
        while(y > 0){
            if(y % 2){
                (*this) *= tmp;
            }
            tmp *= tmp;
            y /= 2;
        }
    }

    constexpr modint operator + (const modint& rhs) const {
        return modint(*this) += rhs;
    }
    constexpr modint operator - (const modint& rhs) const {
        return modint(*this) -= rhs;
    }
    constexpr modint operator * (const modint& rhs) const {
        return modint(*this) *= rhs;
    }
    constexpr modint operator / (const modint& rhs) const {
        return modint(*this) /= rhs;
    }

    
    friend ostream &operator << (ostream& lhs, const modint& rhs){
        return lhs << rhs.num;
    }

    friend istream &operator >> (istream& lhs, modint& rhs){
        lhs >> rhs.num;
        return lhs;
    }
};

#define mint modint<mod>

mint modpow(mint x, ll y){
    if(y == 0) return 1;
    mint e = modpow(x, y / 2);
    e = e * e;
    return e * (y % 2 == 0 ? 1 : x);
}

vector<int> Manacher(string S) {
    vector<int> R(S.size());
    int i = 0, j = 0;
    while (i < (int)S.size()) {
        while (i - j >= 0 && i + j < (int)S.size() && S[i - j] == S[i + j]) ++j;
        R[i] = j;
        int k = 1;
        while (i - k >= 0 && k + R[i - k] < j) R[i + k] = R[i - k], ++k;
        i += k; j -= k;
    }
    return R;
}

random_device rnd;
mt19937 mt(rnd());

struct rolling_hash {
private:
    static inline const ll base = mt();
    static const ll MASK30 = (1ll << 30) - 1;
    static const ll MASK31 = (1ll << 31) - 1;
    static const ll HASH_MOD = (1ll << 61) - 1;
    static const ll MASK61 = HASH_MOD;

    ll calc_mod(ll x) {
        ll xu = x >> 61;
        ll xl = x & MASK61;
        ll ret = xu + xl;
        if (ret >= HASH_MOD) ret -= HASH_MOD;
        return ret;
    }

    ll calc_mul(ll a, ll b) {
        ll au = a >> 31;
        ll al = a & MASK31;
        ll bu = b >> 31;
        ll bl = b & MASK31;
        ll mid = al * bu + au * bl;
        ll midu = mid >> 30;
        ll midl = mid & MASK30;
        return calc_mod(au * bu * 2 + midu + (midl << 31) + al * bl);
    }
public:
    int N;
    string S;
    vector<ll> hash, power;
    rolling_hash(){}
    rolling_hash(string s) : N(s.size()), S(s), hash(N + 1), power(N + 1) {
        assert(base >= 60);
        power[0] = 1, hash[0] = S[0];
        for (int i = 0; i < N; i++) {
            power[i + 1] = calc_mul(power[i], base);
            hash[i + 1] = calc_mod(calc_mul(hash[i], base) + s[i]);
        }
    }

    ll get_hash(int l = 0, int r = -1) {
        if (r == -1) r = N;
        return calc_mod(hash[r] - calc_mul(hash[l], power[r - l]) + HASH_MOD);
    }
};

struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }

    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

int n;
string s;
int main() {
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(20);
    cin >> n >> s;
    
    string s2 = s + s;
    string t(s2.size() * 2 + 1, '$');
    rep (i, s2.size()) t[i * 2 + 1] = s2[i];
    auto rad = Manacher(t);
    rep (i, 2 * n) chmax(rad[i], rad[i + 2 * n]);
    vector<int> idx(2 * n);
    iota(all(idx), 0);
    sort(all(idx), [&](int a, int b) {
        return rad[a] > rad[b];
    });

    rolling_hash rh(t);
    // ハッシュ値, 個数
    gp_hash_table<ll, mint, custom_hash> dp;
    priority_queue<pii> pq;
    rep (ii, 2 * n) {
        int i = idx[ii];
        if (rad[i] == 1) continue;
        if ((rad[i] * 2 - 1) / 2 > n) {
            if (i & 1) rad[i] = ((n + 1) / 2) * 2;
            else rad[i] = (n / 2) * 2 + 1;
        }
        ll h = rh.get_hash(i, i + rad[i]);
        if (dp.find(h) == dp.end()) {
            pq.push({rad[i], i});
        }
        dp[h]++;
    }

    mint ans = 0;
    while (!pq.empty()) {
        auto [r, i] = pq.top();
        pq.pop();
        ll h = rh.get_hash(i, i + r);
        mint val = dp[h];
        ans += (mint)((r * 2 - 1) / 2) * val * val;
        if (r <= 3) continue;
        ll nh = rh.get_hash(i, i + r - 2);
        if (dp.find(nh) == dp.end()) {
            pq.push({r - 2, i});
        }
        dp[nh] += val;
    }

    cout << ans << '\n';
}

这程序好像有点Bug,我给组数据试试?

详细

Test #1:

score: 100
Accepted
time: 1ms
memory: 3472kb

input:

5
01010

output:

39

result:

ok 1 number(s): "39"

Test #2:

score: 0
Accepted
time: 0ms
memory: 3480kb

input:

8
66776677

output:

192

result:

ok 1 number(s): "192"

Test #3:

score: 0
Accepted
time: 0ms
memory: 3572kb

input:

1
1

output:

1

result:

ok 1 number(s): "1"

Test #4:

score: 0
Accepted
time: 0ms
memory: 3528kb

input:

2
22

output:

12

result:

ok 1 number(s): "12"

Test #5:

score: 0
Accepted
time: 0ms
memory: 3476kb

input:

2
21

output:

2

result:

ok 1 number(s): "2"

Test #6:

score: 0
Accepted
time: 0ms
memory: 3520kb

input:

3
233

output:

10

result:

ok 1 number(s): "10"

Test #7:

score: 0
Accepted
time: 1ms
memory: 3576kb

input:

3
666

output:

54

result:

ok 1 number(s): "54"

Test #8:

score: 0
Accepted
time: 372ms
memory: 180784kb

input:

1000000
3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333...

output:

496166704

result:

ok 1 number(s): "496166704"

Test #9:

score: 0
Accepted
time: 1249ms
memory: 606052kb

input:

3000000
2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222...

output:

890701718

result:

ok 1 number(s): "890701718"

Test #10:

score: 0
Accepted
time: 1376ms
memory: 607048kb

input:

3000000
9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999...

output:

224009870

result:

ok 1 number(s): "224009870"

Test #11:

score: 0
Accepted
time: 813ms
memory: 606888kb

input:

3000000
8989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989898989...

output:

51985943

result:

ok 1 number(s): "51985943"

Test #12:

score: 0
Accepted
time: 875ms
memory: 606260kb

input:

3000000
1911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911911...

output:

355676465

result:

ok 1 number(s): "355676465"

Test #13:

score: 0
Accepted
time: 1836ms
memory: 617944kb

input:

3000000
7777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777...

output:

788510374

result:

ok 1 number(s): "788510374"

Test #14:

score: 0
Accepted
time: 1698ms
memory: 607032kb

input:

3000000
5555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555555...

output:

691884476

result:

ok 1 number(s): "691884476"

Test #15:

score: 0
Accepted
time: 1042ms
memory: 606048kb

input:

3000000
0990990909909909099090990990909909909099090990990909909099099090990990909909099099090990990909909099099090990909909909099099090990909909909099090990990909909909099090990990909909909099090990990909909099099090990990909909099099090990990909909099099090990909909909099099090990909909909099090990...

output:

701050848

result:

ok 1 number(s): "701050848"

Test #16:

score: 0
Accepted
time: 603ms
memory: 385632kb

input:

3000000
2772772727727727277272772772727727727277272772772727727277277272772772727727277277272772772727727277277272772727727727277277272772727727727277272772772727727727277272772772727727727277272772772727727277277272772772727727277277272772772727727277277272772727727727277277272772727727727277272772...

output:

486861605

result:

ok 1 number(s): "486861605"

Test #17:

score: 0
Accepted
time: 1176ms
memory: 606088kb

input:

3000000
4554554545545545455454554554545545545455454554554545545455455454554554545545455455454554554545545455455454554545545545455455454554545545545455454554554545545545455454554554545545545455454554554545545455455454554554545545455455454554554545545455455454554545545545455455454554545545545455454554...

output:

450625621

result:

ok 1 number(s): "450625621"

Test #18:

score: 0
Accepted
time: 1224ms
memory: 606100kb

input:

3000000
1181811811818118181181181811818118118181181181811818118118181181181811818118118181181811811818118118181181811811818118181181181811811818118181181181811811818118181181181811818118118181181181811818118118181181181811818118118181181811811818118118181181811811818118181181181811811818118181181181...

output:

649551870

result:

ok 1 number(s): "649551870"

Extra Test:

score: 0
Extra Test Passed