CF 1200 E Compress Words(扩展kmp)

CF 1200 E. Compress Words(扩展kmp)

Problem - E - Codeforces

大意:给出 n 个字符串 , 有一个结果串 , 依次合并第 i 个串和结果串 , 合并的过程中去除结果串的后缀和第i个串前缀的最长公共部分 , 求结果串。

思路:一个串的前缀和另一个串的后缀 , 很容易让人想到 扩展 kmp 算法。

对于 结果串 和 当前要合并的串 , 不难想出可以用扩展 kmp求出结果串后缀对于与合并串的LCP = 结果串后缀的最大长度 , 这就是我们要的答案。

但是这样显然会 T 飞 , 因为随着不断合并 , 结果串越来越长 ,时间复杂度会上升到 n方级别 。 考虑优化 , 我们要求的最长公共部分显然不会超过 min(结果串 , 当前串) , 所以当结果串很长的时候 , 我们只需要用结果串的有效后缀长度去做 扩展 kmp 即可 ,由于所有串总长不超过 1e6 , 所以这样优化之后跑得飞快。

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define IOS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#define int long long
const int N = 1e5 + 10;
const int M = 1e6 + 10;
const int mod = 1e9 + 7;
typedef pair<int,int>PII;

int n;
string s[N] , ans , now;
int z[M] , p[M];

void get_z(string s , string t){
	
	int n = s.size();int m = t.size();
	s = ' ' + s;t = ' ' + t;
	z[1] = n;
	for(int i = 2 , l = 1 , r = 0 ; i <= n ; i ++){
		if(i <= r) z[i] = min(z[i - l + 1] , r - i + 1);
		else z[i] = 0;
		while(s[z[i] + 1] == s[i + z[i]]) z[i] += 1;
		if(i + z[i] - 1 > r) l = i , r = i + z[i] - 1;
	}
	
	for(int i = 1 , l = 1 , r = 0 ; i <= m ; i ++){
		if(i <= r) p[i] = min(z[i - l + 1] , r - i + 1);
		else p[i] = 0;
		while(p[i] + 1 <= n && i + p[i] - 1 <= m && s[p[i] + 1] == t[p[i] + i]) p[i] += 1;
		if(i + p[i] - 1 > r) l = i , r = i + p[i] - 1;  
	}
}

signed main(){

	IOS
	cin >> n;
	for(int i = 1 ; i <= n ; i ++) cin >> s[i];
	ans += s[1];
	for(int i = 1 ; i <= n - 1 ; i ++){
		int x = ans.size();
		int y = s[i + 1].size();
		if(x > y) now = ans.substr(x - y);
		else now = ans;
		get_z(s[i + 1] , now);
		int m = now.size();
		int mx = 0;
		for(int j = 1 ; j <= m ; j ++){
			if(m - j + 1 == p[j]) mx = max(mx , p[j]); 
		}
		ans += s[i + 1].substr(mx);
	}
	
	cout << ans << "\n";

	return 0;
}
//freopen("文件名.in","r",stdin);
//freopen("文件名.out","w",stdout);
相关推荐
GreenTea9 小时前
vLLM 与 SGLang KV Cache 底层实现机制深度调研报告
前端·后端·算法
Bode_20029 小时前
多资源规划(含生产调度、库存管理及产能规划)的创新优化算法
算法·调度
土司大王10 小时前
LeetCode hot100——35.搜索插入位置:Java 二分模板、左闭右开区间与插入点分析
java·算法·leetcode
微三云生态系统架构师-彭丹10 小时前
远方好物S2B2C系统架构:一级分销与保证金托管的合规技术实现
人工智能·算法
土司大王10 小时前
LeetCode hot100——34.在排序数组中查找元素的第一个和最后一个位置:Java 二分模板、边界分析
java·算法·leetcode
罗西的思考11 小时前
机器人模型(WM / WAM / VLA)综合分析与对比:从「看」到「想」再到「做」
人工智能·算法·机器学习
小哈里13 小时前
【知识】从学科到实践:自然・工程・社科・人文|算法・研发・产品・品牌设计
程序人生·算法·产品·设计·工程
小π军13 小时前
最大重叠区间数量
数据结构·算法
镜像视界(浙江)科技有限公司13 小时前
《视频孪生之上:二维展示终结,三维空间计算重构城市逻辑》——跨摄像连续表达 × 三角测量厘米级定位 × 动态轨迹建模,构建新一代城市空间
大数据·人工智能·算法·矩阵·音视频·空间计算
a1879272183114 小时前
【算法】双指针与滑动窗口(二):滑动窗口——吃进、判定、吐出
算法·leetcode·双指针·滑动窗口·原理·模板·算法讲解