专栏文章

题解:P11325 【MX-S7-T3】「SMOI-R2」Monotonic Queue

P11325题解参与者 1已保存评论 0

文章操作

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

当前评论
0 条
当前快照
1 份
快照标识符
@miqzwxqr
此快照首次捕获于
2025/12/04 13:28
3 个月前
此快照最后确认于
2025/12/04 13:28
3 个月前
查看原文
考虑每一个区间设当前区间为lx,rxl_x,r_x,其上一个区间为ly,ryl_y,r_y,发现对于答案贡献仅同rx,lyr_x, l_y有关
并且发现对于ii要么从队头出去, 要么从第一个满足(i<j)(i < j) 并且(ai<aj)(a_i < a_j)jj这里出去,定义jjii出点
dpidp_i表示右端点为ii的答案最大值,所以在(i<j)(i < j)条件下
dpj=dpi+sum[i,j](ai<aj)dp_j = dp_i + sum[i, j] (a_i < a_j) (jjii出点)
dpj=dpi+sum[i+1,j](ai<aj)dp_j = dp_i + sum[i + 1, j] (a_i < a_j) (jj不为ii出点)
综上可以基于维护一个单调栈来维护出点,然后进行dpdp
详情见代码
CPP
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 601000, INF = 2e12;
int dp[N], v[N], sum[N], a[N];
int stc[N], top, n, ans = -INF;
signed main () {
	scanf("%lld", &n);
	for (int i = 1; i <= n; i++) scanf("%lld", &v[i]), sum[i] = sum[i - 1] + v[i]; 
	for (int i = 1; i <= n; i++) scanf("%lld", &a[i]), dp[i] = - INF; 
	for (int i = 1; i <= n; i++) {
		while (top && a[stc[top]] < a[i]) 
			dp[i] = max(dp[i], dp[stc[top]] + sum[i - 1] - sum[stc[top--] - 1]);
		dp[i] = max(dp[i], dp[stc[top]] + sum[i - 1] - sum[stc[top]]);
		stc[++top] = i;
		ans = max(ans, dp[i]);
	}
	cout << ans << '\n';
	return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...