萌新求助,0pts
查看原帖
萌新求助,0pts
530349
天空即为极限楼主2023/1/8 18:16
#include<bits/stdc++.h>
using namespace std;
const int N = 3e6 + 5;
int Next[N], n, m, d1[N], d2[N];
string s, t;

int v1[N], v2[N], tot;

int KMP () {
  int j = 0;
  for (int i = 2; i <= m; i ++) {
    while (j and t[j + 1] != t[i]) j = Next[j];
    j += (t[j + 1] == t[i]);
    Next[i] = j;
  } j = 0;
  for (int i = 1; i <= n; i ++) {
    while (j and t[j + 1] != s[i]) j = Next[j];
    j += (t[j + 1] == s[i]);
    if(j == m) v1[++ tot] = i - j + 1, v2[tot] = i, j = Next[j];
  }
}

void Manacher () {
  int l = 0, r = -1, j;
  for (int i = 1; i <= n; i ++) {
    if (i <= r) j = min (d1[r - i + 1], r - i + 1); else j = 0;
    while (i - j > 0 and i + j < n + 1 and s[i - j] == s[i + j]) ++ j;
    d1[i] = j --; if (i + j > r) r = i + j, l = i - j;
  }

  for (int i = 1; i <= n; i ++) {
    if (i < r) j = min (d2[r - i + l - 1], r - i); else j = 0;
    while (i - j > 0 and i + 1 + j <= n and s[i - j] == s[i + j + 1]) ++ j;
    d2[i] = j --; if (i + j + 1 > r) r = i + j + 1, l = i - j;
  }
}

int Do(int x) {
  int ans = 0, l = x - d1[x] + 1, r = x + d1[x] - 1;
  int rankl = lower_bound(v1 + 1, v1 + tot + 1, l) - (v1 + 1);
  int rankr = upper_bound(v2 + 1, v2 + tot + 1, r) - (v2 + 1);
  
  if(rankr >= rankl) ans += rankr - rankl;
  l = x - d2[x] + 1, r = x + d2[x];
  
  rankl = lower_bound(v1 + 1, v1 + tot + 1, l) - (v1 + 1);
  rankr = upper_bound(v2 + 1, v2 + tot + 1, r) - (v2 + 1);
 // cout << l << " " << r << " ";
 // cout << rankl << " " << rankr << "\n";
  if(rankr >= rankl) ans += rankr - rankl;
  return ans;
}

int main () {
  cin >> n >> m;
  if (n < m) { cout << "0\n"; return 0; }
  cin >> s >> t; s = '&' + s; t = '&' + t; KMP (); Manacher ();
  int ans = 0;
//  for (int i = 1; i <= tot; i ++) cout << v2[i] << " ";
  for (int i = 1; i <= n; i ++) ans += Do(i);
  cout << ans << "\n";
}

思路是跑一遍kmp和manacher, 在二分匹配串,或许是错的?

2023/1/8 18:16
加载中...