萌新初学 SAM, WA + MLE + TLE + RE,救命
查看原帖
萌新初学 SAM, WA + MLE + TLE + RE,救命
118196
zimujun楼主2021/2/23 14:18

RT

几乎对着板子代码抄的

最后统计 endpos 等价类表示起始位置的个数的时候一开始用的 dfs, MLE

后来改成了拓扑排序 WA + RE + TLE

Code:

SAM

int to[Maxn << 1][26], len[Maxn << 1], link[Maxn << 1], cnt = 1, last = 1;
LL siz[Maxn << 1], Max;

void extend(int c) {
  int cur = ++cnt; len[cur] = len[last] + 1;
  int p = last;
  while(p && (!to[p][c])) {
    to[p][c] = cur;
    p = link[p];
  }
  if(!p) link[cur] = 1;
  else {
    int q = to[p][c];
    if(len[p] + 1 == len[q]) link[cur] = q;
    else {
      int cl = ++cnt; len[cl] = len[p] + 1;
      for(int i = 0; i < 26; ++i) to[cl][i] = to[q][i];
      link[cl] = link[q]; link[q] = link[cur] = cl;
      while(p && to[p][c] == q) to[p][c] = cl, p = link[p];
    }
  }
  last = cur;
  siz[cur] = 1;
}

dfs

struct e {
  int to, nxt;
} b[Maxn << 1];
int head[Maxn], ecnt;
void add(int u, int v) {b[++ecnt] = (e) {v, head[u]}; head[u] = ecnt;}
string s;
void dfs(int t) {
  for(int i = head[t]; i; i = b[i].nxt) {
    dfs(b[i].to); siz[t] += siz[b[i].to];
  }
  if(siz[t] > 1) Max = max(Max, 1ll * len[t] * siz[t]);
}
}

toposort:

int ind[Maxn];
queue<int> que;

int main() {
  cin >> s; int n = s.size();
  for(int i = 0; i < n; ++i) extend(s[i] - 'a');
  for(int i = 2; i <= cnt; ++i) ind[link[i]]++;
  for(int i = 1; i <= cnt; ++i) if(!ind[i]) que.push(i);
  while(!que.empty()) {
    int t = que.front(); que.pop();
    if(siz[t] > 1) Max = max(Max, 1ll * siz[t] * len[t]);
    siz[link[t]] += siz[t];
    ind[link[t]]--; if(!ind[link[t]] && link[t]) que.push(link[t]); 
  }
  printf("%lld", Max);
  return 0;
}
2021/2/23 14:18
加载中...