QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#94697 | #3238. Just So You Know | whatever# | 100 ✓ | 2770ms | 123728kb | C++17 | 3.3kb | 2023-04-07 15:34:40 | 2023-04-07 15:34:41 |
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; }
mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
int rng(int l, int r) { return l + rnd() % (r - l + 1); }
const int N = 1000005;
int n, m, rk[N << 1], sa[N], tp[N << 1], tax[N];
int par[N], siz[N], s[N];
vector<int> e[N];
i64 cnt[N];
void radixSort() {
memset(tax + 1, 0, m * 4);
rep(i, 1, n) ++tax[rk[i]];
rep(i, 1, m) tax[i] += tax[i - 1];
per(i, n, 1) sa[tax[rk[tp[i]]]--] = tp[i];
}
void suffixSort() {
m = 0;
rep(i, 1, n) rk[i] = ++s[i], tp[i] = i, m = max(m, s[i]);
rep(i, 1, n) rk[i + n] = tp[i + n] = 0;
radixSort();
for (int len = 1, p; p < n; len <<= 1, m = p) {
p = 0;
for (int i = 1; i <= len; i++) tp[++p] = n - len + i;
for (int i = 1; i <= n; i++) {
if (sa[i] > len) {
tp[++p] = sa[i] - len;
}
}
radixSort();
rep(i, 1, 2 * n) swap(rk[i], tp[i]);
rk[sa[1]] = p = 1;
for (int i = 2; i <= n; i++) {
rk[sa[i]] = (tp[sa[i]] == tp[sa[i - 1]] && tp[sa[i] + len] == tp[sa[i - 1] + len]) ? p : ++p;
}
}
}
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;
if (siz[x] > siz[y]) swap(x, y);
par[x] = y, siz[y] += siz[x];
cnt[siz[y]] += t;
}
void solve() {
cin >> n;
rep(i, 1, n) cin >> s[i];
suffixSort();
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;
static i64 pq[N];
int tot = 0, 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[++tot] = 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[++tot] = i * 2;
if (cnt[i]) last = i;
}
int ptr = 1;
if (~last) pq[0] = last, --ptr;
while (ptr < tot) {
ans += pq[ptr] + pq[ptr + 1];
pq[++tot] = pq[ptr] + pq[ptr + 1];
ptr += 2;
}
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: 100
Accepted
time: 2770ms
memory: 123728kb
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:
10162982/534061 1822548/95141 1439479/75705 9482159/500500 9125305/482653 9906679/521731 2578847/135330 9723685/512578 10689801/559153 2036941/107019 730583/38369 10076351/529935 9125312/482653 3134105/165502 4892247/257810 11092847/578350 47969/2511 1607141/84756 11251438/585903 10359120/543403 147...
result:
ok 1000 lines