牛客练习赛42 A 字符串
题目描述
给定两个等长的由小写字母构成的串 A,BA,B,其中 |A|=|B|=n|A|=|B|=n。
现在你需要求出一个子区间 [l,r][l,r] 使得 LCP(A[l,r],B[l,r])×LCS(A[l,r],B[l,r])+LCP(A[l,r],B[l,r])+LCS(A[l,r],B[l,r])LCP(A[l,r],B[l,r])×LCS(A[l,r],B[l,r])+LCP(A[l,r],B[l,r])+LCS(A[l,r],B[l,r]) 最大,并输出这个值。
现在你需要求出一个子区间 [l,r][l,r] 使得 LCP(A[l,r],B[l,r])×LCS(A[l,r],B[l,r])+LCP(A[l,r],B[l,r])+LCS(A[l,r],B[l,r])LCP(A[l,r],B[l,r])×LCS(A[l,r],B[l,r])+LCP(A[l,r],B[l,r])+LCS(A[l,r],B[l,r]) 最大,并输出这个值。
LCP(S,T)LCP(S,T)表示S和T的最长公共前缀,LCS(S,T)LCS(S,T)表示S和T的最长公共后缀。
输入描述:
第一行一个字符串 AA。
第二行一个字符串 BB 。
输出描述:
一行一个整数,表示答案。
备注:
对于所有数据,保证 n≤200000n≤200000 ,串 A,BA,B 仅由小写字母构成。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #include <iostream> 6 #include <algorithm> 7 #include <cmath> 8 #include <queue> 9 #include <set> 10 #include <map> 11 #include <stack> 12 #define pi acos(-1.0) 13 #define ll long long 14 #define P pair<ll,ll> 15 #define pu push_back 16 using namespace std; 17 const int N =2e5+1000; 18 char s[N],p[N]; 19 ll mx1,mx2; 20 //题意很简单,注意一定要前后都扫一遍(我只扫了一遍,不停WA) 21 //因为可能是同一个小区间,此时就取那个区间 22 //如 ab cb 1*1+1+1=3 23 int main() 24 { 25 scanf("%s%s",s,p); 26 int l =strlen(s); 27 mx1=0,mx2=0; 28 ll ans=0;//ans :当前状态下公共缀的长度,只要s,p的某个对应字母一样就有公共缀了。 29 //起初,一直在考虑必须至少连续两个一样才有公共缀(错误) 30 for(int i =0;i<l;i++){ 31 if(s[i]==p[i]) { 32 ans++; 33 } 34 else{ 35 ans=0; 36 } 37 mx1=max(mx1,ans); 38 } 39 ans=0; 40 for(int i =l-1;i>=0;i--){ 41 if(s[i]==p[i]) { 42 ans++; 43 } 44 else{ 45 ans=0; 46 } 47 mx2=max(mx2,ans); 48 } 49 printf("%lld\n",mx1*mx2+mx1+mx2); 50 return 0; 51 }