思路:枚举第一个字符串的位置,然后枚举最长公共前缀的长度,时间即会下降……
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<cmath>
#include<bitset>
#define mem(a,b) memset(a,b,sizeof(a))
#define lson i<<1,l,mid
#define rson i<<1|1,mid+1,r
#define llson j<<1,l,mid
#define rrson j<<1|1,mid+1,r
#define seed 131
#define INF 0x7fffffff
#define maxn 200105
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
ull base[maxn],hash1[maxn],hash2[maxn];
int n,m;
char s1[maxn],s2[maxn];
int judge(int i,int j)
{
int l=0,r=m,mid,ans=0;
while(l<=r)
{
mid=(l+r)>>1;//二分最长公共前缀
if(i+mid-1>n||j+mid-1>m)
{
r=mid-1;
continue;
}
ull a=hash1[i+mid-1]-hash1[i-1]*base[mid];
ull b=hash2[j+mid-1]-hash2[j-1]*base[mid];
if(a==b) l=mid+1,ans=mid;
else r=mid-1;
}
return ans;
}
int main()
{
freopen("1.txt","r",stdin);
int i,t,ii=1,flag;
scanf("%d",&t);
for(i=1,base[0]=1;i<maxn;i++)
base[i]=base[i-1]*seed;
while(t--)
{
scanf("%s%s",s1,s2);
n=strlen(s1),m=strlen(s2);
for(i=1,hash1[0]=0;i<=n;i++)
hash1[i]=hash1[i-1]*seed+s1[i-1]-'a'+1;
for(i=1,hash2[0]=0;i<=m;i++)
hash2[i]=hash2[i-1]*seed+s2[i-1]-'a'+1;
for(i=1;i<=n-m+1;i++)//枚举第一个字符串的起始位置
{
int j=1,k=i,cnt=0;
flag=0;
while(k<=n)
{
int len=judge(k,j);//两个位置的最长公共前缀
k+=len+1;
j+=len+1;
cnt++;
if(cnt==2)
{
if(j>m||j+judge(k,j)>m) flag=1;
break;
}
if(j>m) {flag=1;break;}
}
if(flag) break;
}
if(flag) printf("Case #%d: %d\n",ii++,i-1);
else printf("Case #%d: -1\n",ii++);
}
return 0;
}