CF1603C Extreme Extension (数论+dp)

CF1603C Extreme Extension

upd 2024.11.14

数论+dp

首先要思考的一定是怎么操作操作次数会最小。然后就会发现一种贪心策略,即让每次分裂出来的最前面的数尽可能大。

求它的所有非空子段的极端值之和不好直接求,但它等价于求每个位置可能的操作次数(可重)之和。(答案的转化)

由上面可以发现,一个数的操作次数只与上一个数操作后的最前面的数有关,也就是说与前面的数无关,所以对最后的这个数的操作次数只有系数的影响。

那我们就考虑 dp 求解每个位置的贡献。维护什么贡献?

”如果知道上一个位置操作后的最前面的数,也就知道现在位置的操作次数“(充分不必要),那我们只需要知道有多少个子段能够得到这个操作次数就好了。

所以设状态 fi,v 表示有多少以 ai 为开头的子段,使得 ai 拆分完之后最小值为 v。转移 fi,pfi+1,v

复杂度 O(nV)。怎么优化?需要注意到下取整的性质,每个 ai 最多只有 ai 种取值。所以每个阶段最多有根号级别的转移量,那我们只需要枚举这些数就行了。

拿到一题有神秘操作的题目,先考虑把神秘操作搞清楚

对于一个子段,最末尾的数一定不能动,考虑从后往前贪心,当出现 ai>ai+1 时,需要将 ai 拆分。要使当前操作最优,我们要让拆分完的第一个数尽可能大,手算一下就可以得出结论:一共需要拆分 aiai+11 次,第一个数的最大值为 aiaiai+1

此时根据 ai 只被 ai+1 影响,可以考虑 dp,设 fi,v 表示有多少以 ai 为开头的子段,使得 ai 拆分完之后最小值为 v

考虑转移,朴素的做法,枚举所有 fi+1,x,此时 c=aiai+1p=aic,转移到对应的 fi,p 中,复杂度为 O(nV),无法通过。

发现对于每一个 i+1,最多只能转移到 ai+1 个状态中,而对于每个 i,也只有 ai+1 个状态不为零,可以继续转移。这个结论可以用数论分块证明。

所以考虑优化 dp,首先滚动数组,空间复杂度为 O(n)。用两个 vector 维护,将 i+1 的所有不为零的状态用 vector 存起来,转移到对应的 fi,p 里。再将 i 中不为零的状态用另一个 vector 存起来。

考虑按位计算答案,对于每个 (i,v),贡献为 i×(c1)×fi,v,乘法满足分配律,我们在转移的同时更新答案即可。

复杂度降到 O(nV)

#include <bits/stdc++.h>

typedef long long i64;

const int mod = 998244353;

void Solve() {
	int n;
	std::cin >> n;

	std::vector<int> a(n + 1);

	int mx = 0;
	for(int i = 1; i <= n; i++) {
		std::cin >> a[i];
		mx = std::max(mx, a[i]);
	}

	std::vector<std::vector<int>> dp(2, std::vector<int> (mx + 1));
	std::vector<int> v[2];
	int op = 1;
	i64 ans = 0;
	for(int i = n; i >= 1; i--) {
		dp[op][a[i]] = 1;
		v[op].push_back(a[i]);
		int lst = a[i];
		for(auto x : v[op ^ 1]) {
			int cnt = (a[i] + x - 1) / x;
			int num = a[i] / cnt;
			ans = (ans + (i64)i * (cnt - 1) % mod * dp[op ^ 1][x]) % mod;
			dp[op][num] += dp[op ^ 1][x];
			if(num != lst) {
				v[op].push_back(num), lst = num;
			}
		}	
		for(auto x : v[op ^ 1]) {
			dp[op ^ 1][x] = 0;
		}
		v[op ^ 1].clear();
		op ^= 1;
	} 

	std::cout << ans << "\n";
}
int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
	
	int t;
	std::cin >> t;

	while(t--) Solve();

	return 0;
}
posted @   Fire_Raku  阅读(3)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
点击右上角即可分享
微信分享提示