牛客 武辰延的字符串 ###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 }
View Code

 

posted @ 2021-02-24 21:56  canwinfor  阅读(306)  评论(0)    收藏  举报