QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#94681#3238. Just So You Knowwhatever#0 0ms0kbC++173.2kb2023-04-07 15:11:452023-04-07 15:11:49

Judging History

This is the latest submission verdict.

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-04-07 15:11:49]
  • Judged
  • Verdict: 0
  • Time: 0ms
  • Memory: 0kb
  • [2023-04-07 15:11:45]
  • Submitted

answer

#include <bits/stdc++.h>
#define rep(i, a, b) for (int i = a, I = b; i <= I; ++i)
#define per(i, a, b) for (int i = a, I = b; i >= I; --i)
using namespace std;
using i64 = long long;
using i128 = __int128_t;
template<typename T> void up(T &x, T y) { x < y ? x = y : 0; }
template<typename T> void down(T &x, T y) { x > y ? x = y : 0; }

const int N = 1000005;
using pii = pair<int, int>;
int n, rk[N], sa[N], pot[N], par[N], siz[N], s[N];
pair<pii, int> x[N], y[N];
vector<int> e[N];
i64 cnt[N];

int find(int x) {
    while (x != par[x]) x = par[x] = par[par[x]];
    return x;
}
void merge(int u, int v, int t) {
    int x = find(u), y = find(v);
    cnt[siz[x]] -= t, cnt[siz[y]] -= t;
    par[x] = y, siz[y] += siz[x];
    cnt[siz[y]] += t;
}

void solve() {
    cin >> n;
    rep(i, 1, n) cin >> s[i], rk[i] = s[i];
    for (int k = 1, t = 0; k <= n; k <<= 1) {
        rep(i, 1, n) x[i] = {pii(rk[i], (i + k) <= n ? rk[i + k] : 0), i};
        if (k == 1) {
            sort(x + 1, x + n + 1);
        } else {
            memset(pot + 1, 0, t * 4);
            rep(i, 1, n) ++pot[x[i].first.second];
            rep(i, 1, t) pot[i] += pot[i - 1];            
            rep(i, 1, n) y[pot[x[i].first.second]--] = x[i];
            memset(pot + 1, 0, t * 4);
            rep(i, 1, n) ++pot[y[i].first.first];
            rep(i, 1, t) pot[i] += pot[i - 1];
            per(i, n, 1) x[pot[y[i].first.first]--] = y[i];
        }
        int t1 = 0;
        rep(i, 1, n) {
            if (i == 1 || x[i].first.first != x[i - 1].first.first || x[i].first.second != x[i - 1].first.second) ++t1;
            rk[x[i].second] = t1;
        }
        t = t1;
        if (t == n) break;
    }
    rep(i, 1, n) sa[rk[i]] = i;

    rep(i, 0, n) e[i].clear();
    rep(i, 1, n) par[i] = i, siz[i] = 1, cnt[i] = 0;
    for (int i = 1, k = 0; i <= n; ++i) {
        if (k) --k;
        if (rk[i] == 1) continue;
        int j = sa[rk[i] - 1];
        while (max(i, j) + k <= n && s[i + k] == s[j + k]) ++k;
        e[k].push_back(rk[i]);
    }
    per(i, n, 1) {
        for (auto pos : e[i]) merge(pos - 1, pos, i);
    }
    cnt[1] = 1ll * n * (n + 1) / 2;
    rep(i, 2, n) cnt[1] -= cnt[i] * i;

    i64 ans = 0;
    priority_queue<i64, vector<i64>, greater<i64>> pq;
    int last = -1;
    rep(i, 1, n) {
        if (!cnt[i]) continue;
        if (~last) {
            ans += last + i;
            --cnt[i];
            if (last + i <= n) ++cnt[last + i];
            else pq.push(last + i);
            last = -1;
        }
        i64 cur = cnt[i] / 2;
        ans += cur * i * 2;
        cnt[i] -= cur * 2;
        if (i * 2 <= n) cnt[i * 2] += cur;
        else while (cur--) pq.push(i * 2);
        if (cnt[i]) last = i;
    }
    if (~last) pq.push(last);
    while ((int) pq.size() > 1) {
        i64 x = pq.top(); pq.pop();
        i64 y = pq.top(); pq.pop();
        ans += x + y, pq.push(x + y);
    }

    i64 ans1 = 1ll * n * (n + 1) / 2;
    i64 g = __gcd(ans, ans1);
    ans /= g, ans1 /= g;
    if (ans1 == 1) cout << ans << "\n";
    else cout << ans << "/" << ans1 << "\n";
}

int main() {
	ios::sync_with_stdio(0), cin.tie(0);

    int T; cin >> T;
    while (T--) solve();    

	return 0;
}

详细

Test #1:

score: 0
Time Limit Exceeded

input:

1000
1033
25 82 89 85 87 49 93 78 46 30 16 55 39 50 47 99 88 31 80 70 27 85 5 2 65 40 87 6 18 34 42 68 61 73 68 36 47 8 28 83 88 19 13 27 89 64 67 26 65 35 55 50 41 5 96 54 47 82 15 85 97 62 61 36 20 49 35 9 51 89 49 91 59 12 40 63 27 39 56 49 92 45 79 34 37 78 1 2 23 53 15 0 14 13 42 30 53 80 80 79...

output:


result: