QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#300110 | #7901. Basic Substring Structure | willow | RE | 3ms | 31252kb | C++14 | 5.9kb | 2024-01-07 18:10:14 | 2024-01-07 18:10:15 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;
int nxt[maxn], ex[maxn];
// void Getnxt(int *a, int n) {
// int i = 0, j, po;
// nxt[0] = n;
// while(a[i] == a[i + 1] && i + 1 < n)
// ++ i;
// nxt[1] = i, po = 1;
// for(int i = 2; i < n; ++ i) {
// if(nxt[i - po] + i < nxt[po] + po)
// nxt[i] = nxt[i - po];
// else {
// j = nxt[po] + po - i;
// if(j < 0)
// j = 0;
// while(i + j < n && a[j] == a[j + i])
// ++ j;
// nxt[i] = j;
// po = i;
// }
// }
// }
// void Exkmp(int *a, int *b, int n, int m) {
// int i = 0, j, po;
// Getnxt(b, m);
// while(a[i] == b[i] && i < n && i < m)
// ++ i;
// ex[0] = i;
// po = 0;
// for(int i = 1; i < n; ++ i) {
// if(nxt[i - po] + i < ex[po] + po)
// ex[i] = nxt[i - po];
// else {
// j = ex[po] + po - i;
// if(j < 0)
// j = 0;
// while(i + j < n && j < m && a[j + i] == b[j])
// ++ j;
// ex[i] = j;
// po = i;
// }
// }
// }
int n, a[maxn];
namespace SA {
int Mem[maxn * 10], sa[maxn], h[maxn], rk[maxn];
void Build(int m) {
int *x = Mem, *y = Mem + (maxn << 1), *z = y + (maxn << 1);
for(int i = 1; i <= m; ++ i) z[i] = 0;
for(int i = 1; i <= n; ++ i) ++ z[x[i] = a[i]];
for(int i = 1; i <= m; ++ i) z[i] += z[i - 1];
for(int i = 1; i <= n; ++ i) sa[z[x[i]] --] = i;
for(int k = 1; k <= n; k <<= 1) {
int p = 0;
for(int i = n - k + 1; i <= n; ++ i) y[++ p] = i;
for(int i = 1; i <= n; ++ i) if(sa[i] > k) y[++ p] = sa[i] - k;
for(int i = 1; i <= m; ++ i) z[i] = 0;
for(int i = 1; i <= n; ++ i) ++ z[x[i]];
for(int i = 1; i <= m; ++ i) z[i] += z[i - 1];
for(int i = n; i; -- i) sa[z[x[y[i]]] --] = y[i];
swap(x, y); p = 0;
for(int i = 1; i <= n; ++ i) x[sa[i]] = (y[sa[i]] == y[sa[i - 1]] && y[sa[i] + k] == y[sa[i - 1] + k]) ? p : ++ p;
if(p == n) break;
m = p;
}
}
int st[20][maxn], bin[maxn];
void Geth() {
int w = 0;
for(int i = 1; i <= n; ++ i) {
rk[sa[i]] = i;
}
for(int i = 1; i <= n; ++ i) {
if(w) -- w;
if(rk[i] == n)
continue;
while(a[i + w] == a[sa[rk[i] + 1] + w]) ++ w;
h[rk[i]] = w;
}
bin[1] = 0;
for(int i = 2; i <= n; ++ i)
bin[i] = bin[i >> 1] + 1;
for(int i = 1; i < n; ++ i) {
st[0][i] = h[i];
}
for(int j = 1; j < 20; ++ j) {
for(int i = 1; i + (1 << j) - 1 < n; ++ i) {
st[j][i] = min(st[j - 1][i], st[j - 1][i + (1 << (j - 1))]);
}
}
}
int Lcp(int l, int r) {
if(l > n || r > n)
return 0;
if(l == r)
return n - l + 1;
l = rk[l], r = rk[r];
if(l > r)
swap(l, r);
-- r;
int k = bin[r - l + 1];
return min(st[k][l], st[k][r - (1 << k) + 1]);
}
}
int T;
long long dif2[maxn], dif1[maxn], val[maxn];
map<int, int> chg[maxn];
void Sub(int l, int r, int s) {
// cerr << "Sub(" << l << ", " << r << ", " << s << ")" << endl;
dif2[r] -= s;
dif2[r - 1] -= 1 - s;
dif2[l - 1] += s + (r - l + 1);
if(l > 1)
dif2[l - 2] -= s + (r - l);
}
int main() {
// Sub(2, 2, 1);
// Sub(1, 1, 1);
// Sub(5, 5, 1);
// Sub(1, 1, 1);
// Sub(7, 7, 1);
// Sub(1, 1, 1);
// Sub(9, 9, 1);
// Sub(1, 1, 1);
// for(int i = 1; i <= 12; ++ i)
// cerr << dif2[i] << " ";
// cerr << endl;
// for(int i = 12; i; -- i)
// dif1[i] += dif1[i + 1] + dif2[i];
// for(int i = 1; i <= 12; ++ i)
// cerr << dif1[i] << " ";
// cerr << endl;
// for(int i = 12; i; -- i)
// val[i] += val[i + 1] + dif1[i];
// for(int i = 1; i <= 12; ++ i)
// cerr << val[i] << " ";
// cerr << endl;
for(scanf("%d", &T); T --; ) {
scanf("%d", &n);
for(int i = 1; i <= n + 1; ++ i) {
val[i] = dif1[i] = dif2[i] = 0;
chg[i].clear();
}
for(int i = 1; i <= n; ++ i) {
scanf("%d", &a[i]);
}
SA :: Build(n);
SA :: Geth();
// Exkmp(a, a, n, n);
long long sum = 0;
for(int i = 1; i <= n; ++ i) {
ex[i] = SA :: Lcp(1, i);
sum += ex[i];
}
for(int i = 2; i <= n; ++ i) {
if(i > ex[i] + 1) { // no cross
if(ex[i]) {
Sub(i, i + ex[i] - 1, 1);
Sub(1, ex[i], 1);
}
if(i + ex[i] <= n) {
int lcp = SA :: Lcp(1 + ex[i] + 1, i + ex[i] + 1) + 1;
// cerr << i << " " << ex[i] << " " << lcp << endl;
// change a[1 + ex[i]] to a[i + ex[i]]
chg[1 + ex[i]][a[i + ex[i]]] += lcp;
// change a[i + ex[i]] to a[1 + ex[i]]
if(1 + ex[i] + lcp >= i + ex[i]) {
// cerr << "? " << endl;
if(a[i + i + ex[i] - 1] == a[1 + ex[i]]) {
lcp = i + SA :: Lcp(1 + ex[i] + i, i + ex[i] + i);
}
if(a[1 + ex[i]] != a[i + i + ex[i] - 1]) {
lcp = i - 1;
}
}
chg[i + ex[i]][a[1 + ex[i]]] += lcp;
}
}
else { // have cross
Sub(i, i + ex[i] - 1, 1);
Sub(1, i - 1, ex[i] - i + 2);
int lcp = SA :: Lcp(1 + ex[i] + 1, i + ex[i] + 1) + 1;
// cerr << i << " " << ex[i] << " " << lcp << endl;
if(1 + ex[i] + lcp >= i + ex[i]) {
// cerr << "? " << endl;
if(a[i + i + ex[i] - 1] == a[1 + ex[i]]) {
lcp = i + SA :: Lcp(1 + ex[i] + i, i + ex[i] + i);
}
if(a[1 + ex[i]] != a[i + i + ex[i] - 1]) {
lcp = i - 1;
}
}
chg[i + ex[i]][a[1 + ex[i]]] += lcp;
}
}
// for(int i = 1; i <= n; ++ i)
// cerr << dif2[i] << " ";
// cerr << endl;
for(int i = n; i; -- i)
dif1[i] += dif1[i + 1] + dif2[i];
// for(int i = 1; i <= n; ++ i)
// cerr << dif1[i] << " ";
// cerr << endl;
for(int i = n; i; -- i)
val[i] += val[i + 1] + dif1[i];
// for(int i = 1; i <= n; ++ i)
// cerr << val[i] << " ";
// cerr << endl;
long long ans = 0;
// cerr << sum << endl;
for(int i = 1; i <= n; ++ i) {
int mx = 0;
for(auto [x, y] : chg[i]) {
// cerr << "Change " << i << " to " << x << " val = " << y << endl;
mx = max(mx, y);
}
// cerr << "Pos " << i << ": val = " << val[i] << " ans = " << sum + val[i] + mx << endl;
ans += (sum + val[i] + mx) ^ i;
}
printf("%lld\n", ans);
}
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 3ms
memory: 31252kb
input:
2 4 2 1 1 2 12 1 1 4 5 1 4 1 9 1 9 8 10
output:
15 217
result:
ok 2 lines
Test #2:
score: -100
Runtime Error
input:
10000 8 2 1 2 1 1 1 2 2 9 2 2 1 2 1 2 1 2 1 15 2 1 2 1 1 1 1 2 2 1 2 1 2 2 1 2 1 1 10 2 1 1 1 2 2 1 1 2 2 3 2 1 2 11 1 2 2 1 1 2 1 2 2 1 1 14 2 1 1 1 1 2 1 1 1 2 2 1 2 1 12 2 2 2 1 2 2 2 1 1 2 1 2 4 2 1 1 2 8 1 2 2 2 1 2 1 1 8 1 1 2 1 2 1 1 1 6 2 1 1 1 2 2 14 2 2 1 1 1 1 2 2 2 1 2 2 1 1 10 1 2 2 1 1...
output:
94 128 347 3 211 21 265 431 282 15 95 189 117 200455 222 3 335 364 377 452 3 19 122 68 41 83 85 261 10 64 60 227 156 104 252 191 21 54 303 103 102 19 26 68 416 362 270 309 474 349 326 477 231 594 3 402 54 330 8 103 32 147 666 63 338 89 246 3 165 346 245 20 155 3 404 393 392 81 275 360 20 54 59 363 3...