【模板】回文自动机

代码如下

#include <bits/stdc++.h>

using namespace std;

struct PAM {
  struct state {
    int len, sz, fail, cnt; // cnt -> 以该位置结尾的回文子串个数 
    unordered_map<char, int> go;
    state(int _len = 0, int _sz = 0, int _fail = 0) {
      len = _len, sz = _sz, fail = _fail, cnt = 0;
    }
  };
  vector<state> t;
  int tot, last;
  PAM() {
    tot = 2, last = 0;
    t.emplace_back(0, 0, 1); // root of even
    t.emplace_back(-1, 0, 1); // root of odd 
  }
  int extend(string &s, int i) {
    int x = last;
    if (i - t[x].len == 0) x = t[x].fail; // be careful
    while (s[i - 1 - t[x].len] != s[i]) {
      x = t[x].fail;
    }
    if (t[x].go[s[i]] == 0) {
      int z = t[x].fail;
      while (s[i - 1 - t[z].len] != s[i]) {
        z = t[z].fail; 
      }
      int y = tot++;
      t.emplace_back(t[x].len + 2, 0, t[z].go[s[i]]);
      t[x].go[s[i]] = y;
    }
    last = t[x].go[s[i]];
    t[last].sz++;
    t[last].cnt = t[t[last].fail].cnt + 1;
    return t[last].cnt;
  }
};

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0), cout.tie(0);
  string s;
  cin >> s;
  int n = s.size();
  PAM pam;
  for (int i = 0; i < n; i++) {
    int ret = pam.extend(s, i);
    cout << ret << " ";
    if (i < n - 1) {
      s[i + 1] = (ret - 97 + s[i + 1]) % 26 + 97;
    }
  }
  return 0;
} 
posted @ 2019-10-22 20:18  shellpicker  阅读(183)  评论(0编辑  收藏  举报