KMP匹配(Next数组的应用)
题意:
题目链接戳这里QAQ
大致题意就是给你N(1≤N≤300000)个字符串,然后不停的询问,(l,r),求最长的len是r的前缀子串与l的后缀子串相等的长度,例如样例中(1,3),及l串是AAAA,r串是AACCGGTT,那么最长的len就是AA,及为2。我们只需要将r与l拼接去求Next数组就行,答案就是Next[str.length()];
注意这样的几点这题就很好AC,首先如果l和r相同那么答案就是l.length=r.lenth,其次如果L串为AAAA,R串是AAAAAAA,那么答案只能是AAAA(4)。所以为了避免这种情况我们在处理的时候在r与l串中间加两个不同的字符就可以了。“@#”
KMP戳这 KMP不懂的戳这里。
#include<iostream> #include<stdio.h> #include<string> #include<cstring> #include<algorithm> #include<vector> #include<math.h> #include<map> #include<sstream> #include<list> #define STD using namespace std; #define ll long long #define db double #define ldb long double #define IOS std::ios::sync_with_stdio(false),std::cin.tie(0),std::cout.tie(0); #define MAX 88888888; #define INF 0x7fffffff #define r0 return 0; #define SYP system("pause"); #define endl '\n'; STD; int n; string str[300000 + 7]; string p; int Next[300000 + 7]; void inNext() { int j = 0, k = -1; Next[0] = -1; int plen = p.length(); while (j < plen) { if (k == -1 || p[k] == p[j]) { j++; k++; Next[j] = k; } else { k = Next[k]; } } } int main() { cin >> n; for (int i = 1; i <= n; i++) { cin >> str[i]; } int m; cin >> m; while (m--) { int l, r; cin >> l >> r; p = str[r] +"!#"+ str[l]; inNext(); cout << Next[p.length()] << endl; } }