题目链接:https://vjudge.net/contest/362376#problem/E
题意:给定几个字符串,找最大前缀长度
解题思路:
利用hash来表示字符串,hash[i]=hash[i-1]*p+s[i]-‘a’+1;
其中p设置得比26大,这样可以保证如果hash1[i]>hash2[i]时,i之后永远都不会存在hash1[i]=hash2[i]
因为这一题多次询问,直接for一个个查询肯定会超时。所以使用二分的方法,如果hash1[mid]=hash2[mid],则l=mid+1,否则r=mid-1;
#include<iostream>
#include<cstdio>
#include<string.h>
#include<string>
#include<vector>
using namespace std;
#define ll unsigned long long
const int p=131;
vector<ll> Hash[110000];
int n;
int q;
int x,y;
char str[110000];
int df()
{
int len1=Hash[x].size()-1;
int len2=Hash[y].size()-1;
int r=min(len1,len2);
int l=0;
int ans=0;
while(l<=r)
{
int mid=(l+r)/2;
if(Hash[x][mid]==Hash[y][mid])
l=mid+1,ans=max(mid,ans);
else
r=mid-1;
}
return ans;
}
int main()
{
int t;
int f=0;
cin>>t;
while(t--)
{
cout<<"Case "<<++f<<":"<<endl;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%s",str+1);
int len=strlen(str+1);
Hash[i].push_back(0);
for(int j=1;j<=len;j++)
{
Hash[i].push_back(Hash[i][j-1]*p+str[j]-'a'+1);
}
}
scanf("%d",&q);
for(int i=0;i<q;i++)
{
scanf("%d%d",&x,&y);
x=x-1;
y=y-1;
int pos=df();
cout<<pos<<endl;
}
if(t!=0)
for(int i=0;i<n;i++)
Hash[i].clear();
}
return 0;
}