题意:求两个字符串的最长连续公共子序列
思路:开始直接暴力枚举每个长度,结果超时了。所以需要优化代码,第一个想法就是二分,既然要二分那就要证明这两个字符串公共子序列具有单调性,很显然它们是具有单调性的。
代码:
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<map>
#include<algorithm>
#include<vector>
#define LL long long
#define Max 100005
#define ULL unsigned long long
const LL mod=1e9+7;
const ULL base=131;
const LL LL_MAX=9223372036854775807;
using namespace std;
char a[Max],b[Max];
ULL Hash[Max],p[Max],Hash1[Max];
vector<ULL>v;
inline bool check(int d){
v.clear();
int lena=strlen(a+1),lenb=strlen(b+1);
for(int i=d;i<=lena;i++)
v.push_back(Hash[i]-Hash[i-d]*p[d]);
sort(v.begin(),v.end());
for(int i=d;i<=lenb;i++){
ULL t=Hash1[i]-Hash1[i-d]*p[d];
if(binary_search(v.begin(),v.end(),t))
return true;
}
return false;
}
int main()
{
scanf("%s%s",a+1,b+1);
int lena=strlen(a+1),lenb=strlen(b+1);
p[0]=1;
for(int i=1;i<=lena;i++)
Hash[i]=Hash[i-1]*base+a[i],p[i]=p[i-1]*base;
for(int i=1;i<=lenb;i++)
Hash1[i]=Hash1[i-1]*base+b[i];
int l=0,r=Max,mid,ans;
while(l<=r){
mid=(l+r)/2;
if(check(mid)){
ans=mid;
l=mid+1;
}
else
r=mid-1;
}
printf("%d\n",ans);
return 0;
}