洛谷脚造数据?
查看原帖
洛谷脚造数据?
207996
yzy1Ẽd<ßDream楼主2022/4/7 08:31

可以发现这份代码中枚举前缀的部分 for 循环的方向反了(正确的方向应该是从 n/2\lfloor n/2\rfloor11),然后 SAM 的字符集大小开的 44,结果它过了?

这说明什么?洛谷精心脚造数据,让合法方案唯一,且字符集 {a,b,c,d}\tt\{a,b,c,d\}

#include <bits/stdc++.h>

using namespace std;

#define rep(i, f, t) for (int i = (f), ed##i = (t); i <= ed##i; ++i)
#define re(i, t) rep (i, 1, t)
#define nxt(i, f, g) for (int i = g.h[f]; i; i = g.e[i].n)

template <class T, class E>
__attribute__((always_inline)) inline void up(T &x, E &&y) {
  if (x < y) x = y;
}

const int N = 2e6 + 9;
int n, ed[N], dfn[N], tp[N], sz[N], dep[N], tim, son[N], ans;
char s[N];

struct G {
  int h[N], tot;
  struct E {
    int t, n;
  } e[N];
  inline void Add(int f, int t) { e[++tot] = {t, h[f]}, h[f] = tot; }
} g;

struct SAM {
  struct T {
    int e[4], len, lk;
  } d[N];
  int lst, tot;

  inline void Init() { d[lst = ++tot].lk = 0; }

  inline int Add(int c) {
    if (d[lst].e[c] && d[d[lst].e[c]].len == d[d[lst].e[c]].len + 1) return d[lst].e[c];
    int cur = ++tot, p = lst, cl;
    d[cur].lk = 1, d[cur].len = d[lst].len + 1;
    while (p && !d[p].e[c]) {
      d[p].e[c] = cur;
      p = d[p].lk;
    }
    bool fl = 0;
    if (p) {
      int q = d[p].e[c];
      if (d[p].len + 1 == d[q].len)
        d[cur].lk = q;
      else {
        if (p == lst) fl = 1;
        cl = ++tot;
        d[cl] = d[q], d[cl].len = d[p].len + 1;
        while (p && d[p].e[c] == q) d[p].e[c] = cl, p = d[p].lk;
        d[cur].lk = d[q].lk = cl;
      }
    }
    return lst = (fl ? cl : cur);
  }
} sam;

void Dfs1(int f) {
  dep[f] = dep[sam.d[f].lk] + 1;
  sz[f] = 1;
  nxt (i, f, g) {
    int t = g.e[i].t;
    Dfs1(t), sz[f] += sz[t];
    if (sz[t] > sz[son[f]]) son[f] = t;
  }
}

void Dfs2(int f) {
  dfn[f] = ++tim;
  if (!son[f]) return;
  tp[son[f]] = tp[f], Dfs2(son[f]);
  nxt (i, f, g) {
    int t = g.e[i].t;
    if (t == son[f]) continue;
    tp[t] = t, Dfs2(t);
  }
}

inline int Lca(int u, int v) {
  while (tp[u] != tp[v]) dep[tp[u]] > dep[tp[v]] ? u = sam.d[tp[u]].lk : v = sam.d[tp[v]].lk;
  return dep[u] > dep[v] ? v : u;
}

inline bool Ck(int l1, int l2, int len) {
  if (l1 <= 0 || l2 <= 0) return 0;
  int r1 = l1 + len - 1, r2 = l2 + len - 1;
  if (r1 > n || r2 > n) return 0;
  if (l2 <= r1) return 0;
  int lca = Lca(ed[r1], ed[r2]);
  return sam.d[lca].len >= len;
}

signed main() {
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  cin >> n >> (s + 1);
  sam.Init();
  re (i, n)
    ed[i] = sam.Add(s[i] - 'a');
  rep (i, 2, sam.tot)
    g.Add(sam.d[i].lk, i);
  Dfs1(1), tp[1] = 1, Dfs2(1);
  int now = n;
  re (i, n / 2) {
    now += 2;
    if (!Ck(1, n - i + 1, i)) continue;
    while (!Ck(i + 1, n - i - now + 1, now)) --now;
    up(ans, i + now);
  }
  cout << ans << '\n';
  return 0;
}
2022/4/7 08:31
加载中...