10pts求助
查看原帖
10pts求助
699801
zhangzinan1224楼主2023/4/15 17:19
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 5e5 + 5;
int n, k, L, R, lg[N], dp[N][25], pos[N][25], sum[N], a[N], ans; //dp数组是求 RMQ的;pos[i][j]是在 [i,1<<j] 区间最大值出现的位置 
struct node
{
	int lt, rt, val, pos, start;
	bool operator < (const node &cur) const
	{
		return val < cur.val;
	}
};
priority_queue<node> pq;
void pre_rmq() //预处理 RMQ 
{
	lg[0] = -1;	
	for(int i = 1; i <= n; i++)
		lg[i] = lg[i >> 1] + 1;
	for(int j = 1; (1 << j) <= n; j++)
		for(int i = 1; i + (1 << j) - 1 <= n; i++)
		{
			if(dp[i][j-1] > dp[i + (1 << j-1)][j-1])
			{
				dp[i][j] = dp[i][j-1];
				pos[i][j] = pos[i][j-1];
			}
			else
			{
				dp[i][j] = dp[i + (1 << j-1)][j-1];
				pos[i][j] = pos[i + (1 << j-1)][j-1];
			}
		}
	return;
}
int query_pos(int lef, int rig) //询问最大值出现的位置 
{
	int len = lg[rig - lef + 1];
	if(dp[lef][len] > dp[rig - (1 << len) + 1][len])
		return pos[lef][len];
	else
		return pos[rig - (1 << len) + 1][len];
}
signed main()
{
	cin >> n >> k >> L >> R;
	for(int i = 1; i <= n; i++)
	{
		cin >> a[i];
		pos[i][0] = i;
		sum[i] = sum[i-1] + a[i];
		dp[i][0] = sum[i];
	}
	pre_rmq();
	for(int i = 1; i + L - 1 <= n; i++)
	{
		int pos = query_pos(i + L - 1, min(n, i + R - 1));
		pq.push((node){i + L - 1, min(n, i + R - 1), sum[pos] - sum[i-1], pos, i});
	}
	for(int i = 1; i <= k; i++)
	{
		node cur = pq.top();
		pq.pop();
		ans += cur.val;
		if(cur.pos > cur.lt)
			pq.push((node){cur.lt, cur.pos - 1, sum[query_pos(cur.lt, cur.pos - 1)] - sum[cur.start], query_pos(cur.lt, cur.pos - 1), cur.start});
		if(cur.pos < cur.rt)
			pq.push((node){cur.pos + 1, cur.rt, sum[query_pos(cur.pos + 1, cur.rt)] - sum[cur.start], query_pos(cur.pos + 1, cur.rt), cur.start});
	}
	cout << ans << endl;
	return 0;
}
2023/4/15 17:19
加载中...