为什么不开 O2 WA,开 O2 AC
查看原帖
为什么不开 O2 WA,开 O2 AC
88471
Lskkkno1楼主2020/5/13 14:49

如题,同一份代码无 O2 WA,开 O2 AC。

实测只要把 pos 数组的空间开两倍就能 AC,但是 pos 数组只访问了 1n1 \sim 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;
}
2020/5/13 14:49
加载中...