J. Justice String
2000ms
2000ms
65536KB
64-bit integer IO format:
%lld Java class name:
Main
Font Size:
Given two strings A and B, your task is to find a substring of A called justice string, which has the same length as B, and only has at most two characters different from B.
Input
The first line of the input contains a single integer T, which is the number of test cases.
For each test case, the first line is string A, and the second is string B.
Both string A and B contain lowercase English letters from
a to
z only. And the length of these two strings is between 1 and 100000, inclusive.
Output
For each case, first output the case number as "
Case #x: ", and x is the case number. Then output a number indicating the start position of substring C in A, position is counted from 0. If there is no such substring C, output -1.
And if there are multiple solutions, output the smallest one.
Sample Input
3 aaabcd abee aaaaaa aaaaa aaaaaa aabbb
Sample Output
Case #1: 2 Case #2: 0 Case #3: -1
哈希,从小到大枚举答案起始位置,再二分哈希值比较得出第一个不同点,然后再二分第二个不同点。
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; #define rep(i,s,t) for(int i=s;i<t;i++) typedef long long ll; const ll mod=1000000007; const ll B=26; const int N=100005; char a[N],b[N]; int n,la,lb; ll Pow[N],ha[N],hb[N]; inline void init(){ Pow[0]=1; rep(i,1,N){ Pow[i]=Pow[i-1]*B%mod; } } inline void Hash(char *a,ll *b,int l){ b[0]=(a[0]-'a'); rep(i,1,l){ b[i]=b[i-1]+Pow[i]*(a[i]-'a'); b[i]%=mod; } } inline int BS(int s,int t,int ss){ int mid,r=s; while(s<=t){ mid=(s+t)>>1; ll val=hb[mid-r+ss],vv=ha[mid]; if(ss!=0) val=((val-hb[ss-1])%mod+mod)%mod; if(r!=0) vv=((vv-ha[r-1])%mod+mod)%mod; if(vv*Pow[ss]%mod==val*Pow[r]%mod) s=mid+1; else{ t=mid-1; } } return s; } inline bool ok(int ans){ int s=ans,t=ans+lb-1,tmp,nxt=0; //1st diff tmp=BS(s,t,nxt);//printf("%d %d %d %d zz\n",tmp,t,s,nxt); if(tmp>t){ return 1; } s=tmp+1,nxt=s-ans; //2nd diff tmp=BS(s,t,nxt);//printf("%d %d %d %d hh\n",tmp,t,s,nxt); if(tmp>t){ return 1; } s=tmp+1,nxt=s-ans;//printf("%d %d %d jj\n",t,s,nxt); if(s>t) return 1; ll v1=ha[t]; if(s>0) v1=((v1-ha[s-1])%mod+mod)%mod; ll v2=hb[lb-1]; if(nxt>0) v2=((v2-hb[nxt-1])%mod+mod)%mod; if(v2*Pow[s]%mod == v1*Pow[nxt]%mod) return 1; return 0; } inline void Work(){ int ans=0; while(ans+lb-1<la && !ok(ans)) ans++; if(ans+lb-1>=la) printf("-1\n"); else printf("%d\n",ans); } int main(){ init(); scanf("%d",&n); rep(ca,1,n+1){ scanf("%s%s",a,b); la=strlen(a),lb=strlen(b); Hash(a,ha,la),Hash(b,hb,lb); printf("Case #%d: ",ca); Work(); } return 0; }