Codeforces Round #578 (Div. 2) E. Compress Words ###K ###K //K
题目链接:https://codeforces.ml/problemset/problem/1200/E
题意:给定n个字符串 总长度不超过1e6 每个字符串从头到尾可以合并 要找到最大的i,满足第一个单词的长度为i的后缀和第二个单词长度为i的前缀相等 然后重复的部分只取一遍合并
思路:考虑 暴力 枚举长度 然后慢慢匹配的话要n^2 那么考虑用kmp来匹配来优化,每次匹配的话最多只会匹配到下一个字符串的长度
所以最终匹配的长度最多为1e6 并且kmp匹配 o n 所以复杂度没有问题 所以直接对ans 匹配即可 最后的j剩下多少就证明s有多少前缀和ans的后缀重合了
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e6+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 12 13 int nxt[maxn]; 14 15 int main() 16 { 17 ios::sync_with_stdio(false); 18 cin.tie(0); 19 int t; 20 cin>>t; 21 string ans; 22 cin>>ans; 23 t--; 24 while(t--) 25 { 26 string s; 27 cin>>s; 28 int n=s.size(); 29 s=' '+s; 30 for(int i=2,j=0;i<=n;i++) 31 { 32 while(j&&s[i]!=s[j+1]) j=nxt[j]; 33 if(s[i]==s[j+1]) j++; 34 nxt[i]=j; 35 } 36 int m=ans.size(); 37 int j=0; 38 int st=max(0,m-1-n+1); 39 for(int i=st;i<m;i++) 40 { 41 while(j&&ans[i]!=s[j+1]) j=nxt[j]; 42 if(ans[i]==s[j+1]) j++; 43 } 44 ans+=s.substr(1+j,n); 45 46 } 47 cout<<ans<<'\n'; 48 49 50 51 52 53 54 55 }
                    
                
                
            
        
浙公网安备 33010602011771号