CF 432D Prefixes and Suffixes
借着这道题复习了AC自动机,虽然这题并不需要,但还是有点价值的
kmp+dp
先用 kmp 求出 ne 数组
dp[i]
表示前缀 i 出现的次数,dp[ne[i]] += dp[i]
#include <bits/stdc++.h>
using namespace std;
#define int long long
using i64 = long long;
typedef pair<int, int> PII;
typedef pair<int, char> PIC;
typedef pair<double, double> PDD;
typedef pair<int, PII> PIII;
const int N = 1e5 + 10;
const int mod = 1e9 + 7;
const int maxn = 1e6 + 10;
const int mod1 = 954169327;
const int mod2 = 906097321;
const int INF = 0x3f3f3f3f3f3f3f3f;
void solve()
{
string s;
cin >> s;
int n = s.size();
vector<int> ne(n + 1);
s = '.' + s;
auto get_ne = [&](string s)
{
for (int i = 2; i <= n; i ++ )
{
int j = ne[i - 1];
while (j && s[i] != s[j + 1]) j = ne[j];
if (s[i] == s[j + 1]) j ++ ;
ne[i] = j;
}
};
get_ne(s);
vector<int> dp(n + 1, 1);
for (int i = n; i > 0; i -- )
dp[ne[i]] += dp[i];
vector<PII> ans;
while (n)
{
ans.push_back({n, dp[n]});
n = ne[n];
}
sort(ans.begin(), ans.end());
cout << ans.size() << '\n';
for (auto t : ans) cout << t.first << ' ' << t.second << '\n';
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int t = 1;
// cin >> t;
while (t--)
{
solve();
}
}