社区讨论

对于nlogn复杂度下动态维护GCD区间的思考 & 求题

学术版参与者 2已保存回复 4

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
4 条
当前快照
1 份
快照标识符
@mhz449lw
此快照首次捕获于
2025/11/15 01:09
3 个月前
此快照最后确认于
2025/11/16 13:41
3 个月前
查看原帖
在做题时发现的trick:P5502
我们都知道有一种在 O(nlogn)O(n\log n) 的复杂度下动态维护GCD区间长度的套路:
CPP
vector<pair<int,int>> cur,nxt;
for 每个新元素x:
	nxt.clear();
	nxt.push_back({x,1}); // 新元素单独成段
	
	for 每个旧状态[g,len] in cur:
		new_g = gcd(g,x);
		if new_g == nxt.back().g:
			nxt.back().g = max(nxt.back().g,len+1);
		else:
			nxt.push_back({new_g,len+1});

	cur = nxt;
	更新答案
那么我们是否可以推广到以下形式中: (f需满足结合律:f(a,f(b,c)) = f((a,b),c) 才可以,常用的有:gcd、lcm、min、max、*、&、|、^)
CPP
vector<pair<int,int>> cur,nxt;
for 每个新元素x:
	nxt.clear();
	nxt.push_back({x,1}); // 新元素单独成段
	for 每个旧状态[val,len] in cur:
		new_val = f(new_val,val); // f需满足结合律:f(a,f(b,c)) = f((a,b),c) 才可以,如gcd, min, max等
		if new_val == nxt.back().g:
			合并长度
		else:
			创建新段

	cur = nxt;
	更新答案
这个套路除了可以解决最长区间问题外,还能解决什么问题?有没有推荐题单?求大佬解答

回复

4 条回复,欢迎继续交流。

正在加载回复...