Division + LCP (easy version)
题目描述
This is the easy version of the problem. In this version l = r l=r l=r .
You are given a string s s s . For a fixed k k k , consider a division of s s s into exactly k k k continuous substrings w 1 , … , w k w_1,\dots,w_k w1,…,wk . Let f k f_k fk be the maximal possible L C P ( w 1 , … , w k ) LCP(w_1,\dots,w_k) LCP(w1,…,wk) among all divisions.
L C P ( w 1 , … , w m ) LCP(w_1,\dots,w_m) LCP(w1,…,wm) is the length of the Longest Common Prefix of the strings w 1 , … , w m w_1,\dots,w_m w1,…,wm .
For example, if s = a b a b a b c a b s=abababcab s=abababcab and k = 4 k=4 k=4 , a possible division is a b a b a b c a b \color{red}{ab}\color{blue}{ab}\color{orange}{abc}\color{green}{ab} abababcab . The L C P ( a b , a b , a b c , a b ) LCP(\color{red}{ab},\color{blue}{ab},\color{orange}{abc},\color{green}{ab}) LCP(ab,ab,abc,ab) is 2 2 2 , since a b ab ab is the Longest Common Prefix of those four strings. Note that each substring consists of a continuous segment of characters and each character belongs to exactly one substring.
Your task is to find f l , f l + 1 , … , f r f_l,f_{l+1},\dots,f_r fl,fl+1,…,fr . In this version l = r l=r l=r .
输入格式
The first line contains a single integer t t t ( 1 ≤ t ≤ 1 0 4 1 \le t \le 10^4 1≤t≤104 ) — the number of test cases.
The first line of each test case contains two integers n n n , l l l , r r r ( 1 ≤ l = r ≤ n ≤ 2 ⋅ 1 0 5 1 \le l = r \le n \le 2 \cdot 10^5 1≤l=r≤n≤2⋅105 ) — the length of the string and the given range.
The second line of each test case contains string s s s of length n n n , all characters are lowercase English letters.
It is guaranteed that the sum of n n n over all test cases does not exceed 2 ⋅ 1 0 5 2\cdot 10^5 2⋅105 .
输出格式
For each test case, output r − l + 1 r-l+1 r−l+1 values: f l , … , f r f_l,\dots,f_r fl,…,fr .
样例 #1
样例输入 #1
7
3 3 3
aba
3 3 3
aaa
7 2 2
abacaba
9 4 4
abababcab
10 1 1
codeforces
9 3 3
abafababa
5 3 3
zpozp
样例输出 #1
0
1
3
2
10
2
0
提示
In the first sample n = k n=k n=k , so the only division of a b a aba aba is a b a \color{red}a\color{blue}b\color{orange}a aba . The answer is zero, because those strings do not have a common prefix.
In the second sample, the only division is a a a \color{red}a\color{blue}a\color{orange}a aaa . Their longest common prefix is one.
原题
CF——传送门
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;int n, Left, Right;
const int MAX = 1e6 + 6;
int Next[MAX];
vector<int> ans;
inline void GetNext(string s, int l) // 获得字符串s的Next数组
{int t;Next[0] = -1; // 如果在0位置失配则是向下移动一位for (int i = 1; i < l; ++i) // 依次求解后面的Next数组{t = Next[i - 1];while (s[t + 1] != s[i] && t >= 0)t = Next[t];if (s[t + 1] == s[i])Next[i] = t + 1;elseNext[i] = -1;}
}
inline void KMP(string s1, int l1, string s2, int l2)
{GetNext(s2, l2);int i = 0, j = 0;while (j < l1){if (s2[i] == s1[j]) // 当前位匹配成功,继续匹配下一位{++i;++j;if (i == l2) // 完全匹配{ans.push_back(j - l2); // 储存答案i = Next[i - 1] + 1; // 继续匹配}}else{if (i == 0) // 在首位不匹配j++;elsei = Next[i - 1] + 1;}}
}
bool check(string s, string a, int k)
{KMP(s, s.size(), a, a.size());int num = 0;// 去掉重叠的匹配子串if (ans.size() >= 1){num++;int last = ans[0];for (int i = 1; i < ans.size(); i++){if (ans[i] - last > k - 1){num++;last = ans[i];}}}ans.clear();if (num >= Left)return 1;elsereturn 0;
}
int main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int t;cin >> t;while (t--){cin >> n >> Left >> Right;string s;cin >> s;// 二分int l = 0, r = n / Left;while (l < r){int mid = (l + r + 1) / 2; // 这里要 l + r +1 要不然会死循环string a = s.substr(0, mid);if (check(s, a, mid)) // check函数自己写{l = mid; // mid这个位置 满足条件之后 查找 [mid , right]的位置, 所以l移到mid的位置}else{r = mid - 1; // [mid,r] 不满足条件, 所以要移到满足条件的一方, r = mid - 1}}cout << l << '\n';}return 0;
}