P2048 超级钢琴 0pts 求条
  • 板块灌水区
  • 楼主Z_L_H
  • 当前回复0
  • 已保存回复0
  • 发布时间2025/1/9 16:44
  • 上次更新2025/1/9 22:35:24
查看原帖
P2048 超级钢琴 0pts 求条
1510234
Z_L_H楼主2025/1/9 16:44

rt

#include<bits/stdc++.h>
using namespace std;
int a[500005],sum[500005];
int st[500005][21],mi[50005][21];
int lg[500005];
int intervalminid(int l,int r)
{
	if(st[l][lg[r - l + 1]] <= st[r - (1 << (lg[r - l + 1])) + 1][lg[r - l + 1]])
	{
		return mi[l][lg[r - l + 1]];
	}
	else
	{
		return mi[r - (1 << (lg[r - l + 1])) + 1][lg[r - l + 1]];
	}
}
struct node
{
	int l,r,o;
	bool operator < (const node &a) const
	{
		return intervalminid(l - 1,r - 1) < intervalminid(a.l - 1,a.r - 1);
	}
};
priority_queue <node> q;
priority_queue <node> p;
priority_queue <node> m;
int main()
{
	int n,k,L,R;
	cin>>n>>k>>L>>R;
	for(int i = 1;i <= n;i ++)
	{
		cin>>a[i];
		sum[i] = sum[i - 1] + a[i];
	}
	memset(st,0x3f,sizeof(st));
	for(int i = 1;i <= n;i ++)
	{
		st[i][0] = sum[i];
		mi[i][0] = i;
	}
	for(int i = 2;i <= n;i ++)lg[i] = lg[i / 2] + 1;
	for(int len = 1;len <= lg[n];len ++)
	{
		for(int i = 1;i - 1 + (1 << len) <= n;i ++)
		{
			st[i][len] = min(st[i][len - 1],st[i + (1 << len - 1)][len - 1]);
			if(st[i][len - 1] <= st[i + (1 << len - 1)][len - 1])
			{
				mi[i][len] = mi[i][len - 1];
			}
			else
			{
				mi[i][len] = mi[i + (1 << len - 1)][len - 1];
			}
		}
	}
	for(int i = L;i <= n;i ++)
	{
		int l = max(1,i - R + 1),r = max(1,i - L + 1);
		q.push({l,r,i});
		while(q.size() > k)q.pop();
	}
	while(!q.empty())
	{
		node temp = q.top();
		q.pop();
		m.push(temp);
		m.push({temp.l,intervalminid(temp.l - 1,temp.r - 1) - 1,temp.o});
		m.push({temp.l,intervalminid(temp.l - 1,temp.r - 1) + 1,temp.o});
		while(!m.empty())m.pop();
		p.push(m.top());
	}
	int ans = 0;
	while(!p.empty())
	{
		ans += sum[p.top().r] - sum[p.top().l - 1];
		p.pop();
	}
	cout<<ans;
	return 0;
}
2025/1/9 16:44
加载中...