雜湊是好東西,二分+雜湊是更好的東西
阿新 • • 發佈:2018-12-14
rt
明明能雜湊為什麼要KMP/AC自動機/字尾陣列/字尾自動機/字尾樹呢???????
【XSY2361】LCP
給定串 S,m 組詢問 (X, Y, L, R): 求 S[X:Y] 與 S[L:R] 的最長公共字首.
1 #include<algorithm>
2 #include<iostream>
3 #include<cstring>
4 #include<cstdio>
5 #include<cmath>
6 #include<queue>
7 #define inf 2147483647
8 #define eps 1e-9
9 using namespace std;
10 typedef long long ll;
11 typedef double db;
12 const ll H=173;
13 int len,m,l,r,x,y;
14 ll hs[100001],pw[100001];
15 char s[100001];
16 int work(int L,int R,int x,int y){
17 int l=1,r=min(R-L+1,y-x+1);
18 if(s[L]!=s[x])return 0;
19 while(l<r){
20 int mid=(l+r)/2;
21 if(hs[L]-hs[L+mid]*pw[mid]==hs[x]-hs[x+mid]*pw[mid])l=mid+1;
22 else r=mid;
23 }
24 if(s[L+l-1]!=s[x+l-1])l--;
25 return l;
26 }
27 int main(){
28 scanf("%s",s+1);
29 len=strlen(s+1);
30 pw[0]=1;
31 for (int i=1;i<=len+1;i++)pw[i]=pw[i-1]*H;
32 for(int i=len;i;i--)hs[i]=hs[i+1]*H+s[i]-'a';
33 scanf("%d",&m);
34 for(int i=1;i<=m;i++){
35 scanf("%d%d%d%d",&l,&r,&x,&y);
36 printf("%d\n",work(l,r,x,y));
37 }
38 return 0;
39 }