如题,同一份代码无 O2 WA,开 O2 AC。
实测只要把 pos
数组的空间开两倍就能 AC,但是 pos
数组只访问了 1∼n 好像也不会越界。
求 dalao 帮忙解释一下原因。
给出代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 5;
int n;
long long ans;
char s[N];
int last, vcnt;
int pos[N];
struct node {
int link, len, siz;
int to[26];
} a[N << 1];
vector<int> g[N << 1];
void extend(int c) {
int p = last, cur = ++vcnt;
a[cur].len = a[last].len + 1;
while(~p && !a[p].to[c]) {
a[p].to[c] = cur;
p = a[p].link;
}
if(p == -1) {
a[p].link = 0;
} else {
int q = a[p].to[c];
if(a[q].len == a[p].len + 1) {
a[cur].link = q;
} else {
int clone = ++vcnt;
a[clone] = a[q];
a[clone].len = a[p].len + 1;
while(~p && a[p].to[c] == q) {
a[p].to[c] = clone;
p = a[p].link;
}
a[q].link = a[cur].link = clone;
}
}
last = cur;
}
void dfs(int u) {
for(int v : g[u]) {
dfs(v);
ans -= 2LL * a[u].len * a[u].siz * a[v].siz;
a[u].siz += a[v].siz;
}
}
int main() {
scanf("%s", s + 1), n = strlen(s + 1);
ans = n * (n + 1LL) / 2 * (n - 1);
a[last = 0].link = -1;
for(int i = n; i >= 1; --i) {
extend(s[i] - 'a');
pos[i] = last;
}
for(int i = 1; i <= vcnt; ++i)
g[a[i].link].push_back(i);
for(int i = 1; i <= n; ++i)
++a[pos[i]].siz;
dfs(0);
printf("%lld\n", ans);
return 0;
}