牛客 武辰延的字符串 ###K //K
题目链接:https://ac.nowcoder.com/acm/contest/9984/B
思路:先枚举 si 有多少个能匹配得上, 然后再从i+1的位置开始 找 t 最多能匹配上s的前缀有多少个
字符串哈希后用二分 找最大的k即可 每次长度为k的每一个都能产生贡献,所以每次+k
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e5+10; 4 const int mod=1e9+7; 5 #define ll long long 6 #define ull unsigned long long 7 #define pi pair<int,int> 8 #define fi first 9 #define sc second 10 #define pb push_back 11 ull P=13331; 12 char s[maxn],t[maxn]; 13 ull h[maxn]; 14 ull a[maxn],b[maxn]; 15 16 ull get_s(int l,int r) 17 { 18 if(r<l) r++; 19 return a[r]-a[l-1]*h[r-l+1]; 20 } 21 ull get_t(int l,int r) 22 { 23 if(r<l) r++; 24 return b[r]-b[l-1]*h[r-l+1]; 25 } 26 27 28 int main() 29 { 30 ios::sync_with_stdio(0); 31 cin.tie(0); 32 cin>>(s+1); 33 cin>>(t+1); 34 int ls=strlen(s+1),lt=strlen(t+1); 35 h[0]=1; 36 for(int i=1;i<=max(ls,lt);i++) 37 { 38 h[i]=h[i-1]*P; 39 } 40 for(int i=1;i<=ls;i++) a[i]=a[i-1]*P+s[i]; 41 for(int i=1;i<=lt;i++) b[i]=b[i-1]*P+t[i]; 42 ll ans=0; 43 for(int i=1;i<=ls;i++) 44 { 45 if(s[i]!=t[i]) break; 46 int l=0,r=min(ls,lt-i); 47 while(l<r) 48 { 49 int mid=(l+r+1)/2; 50 if(get_s(1,mid)==get_t(i+1,i+mid)) 51 { 52 l=mid; 53 } 54 else 55 r=mid-1; 56 } 57 ans+=l; 58 } 59 cout<<ans<<'\n'; 60 61 62 63 64 65 }

浙公网安备 33010602011771号