QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#94681 | #3238. Just So You Know | whatever# | 0 | 0ms | 0kb | C++17 | 3.2kb | 2023-04-07 15:11:45 | 2023-04-07 15:11:49 |
Judging History
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...