首页 > 其他分享 >P2048

P2048

时间:2024-09-18 19:01:55浏览次数:9  
标签:lg RMQ int num P2048 left

good rmq

#include<bits/stdc++.h>
using namespace std;
struct node {
	int num;
	int lid,rid;
	int w;
	int data;
	bool operator <(node i)const {
		return data<i.data;
	}
};
int c[500005],dp[500005][20],lg[500005];
int num[500005][20];
int p[500005];
int n,k,l,r;
int minn=2147483647;
long long ans=0;
priority_queue<node>q;
void RMQ() {
	for(int j=1; j<=20; j++) {
		for(int i=1; i<=n; i++) {
			if(i+(1<<j)-1<=n) {
				if(dp[i][j-1]<dp[i+(1<<(j-1))][j-1]) {
					dp[i][j]=dp[i+(1<<(j-1))][j-1];
					num[i][j]=num[i+(1<<(j-1))][j-1];
				} else {
					dp[i][j]=dp[i][j-1];
					num[i][j]=num[i][j-1];
				}
			}
		}
	}
}
int wz(int x,int y) {
	int tmp=lg[y-x+1];
	int o,jl;
	if(dp[x][tmp]>dp[y-(1<<tmp)+1][tmp])
		jl=num[x][tmp];
	else
		jl=num[y-(1<<tmp)+1][tmp];
	return jl;
}
void add(int po,int i,int left,int right) {
	node tmp;
	tmp.w=po;
	tmp.num=i;
	tmp.lid=left;
	tmp.rid=right;
	tmp.data=c[po]-c[i-1];
	q.push(tmp);
	return ;
}
int main() {
	cin>>n>>k>>l>>r;
	lg[0]=-1;
	for(int i=1; i<=n; i++) {
		int x;
		cin>>x;
		c[i]=c[i-1]+x;
		dp[i][0]=c[i];
		num[i][0]=i;
		lg[i]=lg[i/2]+1;
	}
	RMQ();
	for(int i=1; i+l-1<=n; i++)add(wz(i+l-1,min(i+r-1,n)),i,i+l-1,min(i+r-1,n));
	while(k--) {
		int d=q.top().w,left=q.top().lid,right=q.top().rid;
		int e=q.top().data,id=q.top().num;
		ans+=e;
		q.pop();
		if(d>left)add(wz(left,d-1),id,left,d-1);
		if(d<right)add(wz(d+1,right),id,d+1,right);
	}
	cout<<ans<<endl;
	return 0;
}

标签:lg,RMQ,int,num,P2048,left
From: https://www.cnblogs.com/zan-mei-tai-yang/p/18419136

相关文章

  • P2048 [NOI2010] 超级钢琴
    P2048[NOI2010]超级钢琴题目链接其实这道题在我刚学oi两个月(2023.3)就见过了当时是作为st表的一个例题出现的,我学st表就已经学得迷迷糊糊的了,更别说这题了哈哈所以这是第二次见到他,必须写了(这一次他是作为NOIP模拟赛的一个部分分做法出现的)思路不错的限制:每......
  • P2048 [NOI2010] 超级钢琴
    题意在一个数组中选择\(k\)个长度为\([l,r]\)的序列,对每个序列求和,使每个序列的和的和最大。思路首先,我们可以将序列之和转化为前缀和,如果固定左端点\(l\),那么我们只需要在\([l+len_l,l+len_r]\)中寻找最大的右端点,减去\(sum[l-1]\)就是在长度为\([len_l,le......
  • [NOI2010][洛谷P2048]超级钢琴
    一道很不错也很难的ST表Debug了好久之后发现撞变量了......
  • 2023NOIP A层联测9 风信子+P2048 【NOI2010】 超级钢琴 2023
    P2048【NOI2010】超级钢琴2023NOIPA层联测9风信子一年OI一场空,一道原题见祖宗……Ps:超级钢琴是风信子的前置题。超级钢琴题意在一段序列上,选择长度为\(x\)的区间且\(x\in[L,R]\),求选择\(k\)个区间求和的最大值。思路来自洛谷第一篇Nekroz的题解。将区间和......
  • 【题解 P2048】 超级钢琴
    [NOI2010]超级钢琴题目描述小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐。这架超级钢琴可以弹奏出\(n\)个音符,编号为\(1\)至\(n\)。第\(i\)个音符的美妙度为\(A_i\),其中\(A_i\)可正可负。一个......
  • 解题报告P2048 [NOI2010] 超级钢琴
    P2048[NOI2010]超级钢琴题目链接RMQ好题,但是不知道为啥hzoi放到了lca的题单这道题思路想了一半然后卡了,不知道怎么处理重复贡献的问题。然后he了眼题解,茅塞顿开。可以再次将最优分成两个,再次计算。全程维护音符的前缀和,和区间最大值。结构体内存最大值,左端点,右端点范围,以......
  • P2048 超级钢琴 题解
    超级钢琴题目大意求出序列中长度在\([L,R]\)中的所有区间的区间和前\(k\)大的区间的区间和。思路分析暴力做法是把所有符合条件的区间扔进堆里,再弹出\(k\)个,时间复杂度\(O((n^2+k)\logn)\),可以拿到\(20\text{pts}\)的好成绩。但真的有必要全部加进去吗?不!我们设五......
  • [RMQ记录] P2048 [NOI2010] 超级钢琴
    题目如果枚举所有的情况肯定是不行的。不过可以发现一些对答案完全没有影响的答案也被枚举,十分浪费时间,所以下面介绍一种很好的思路。首先,考虑优化暴力(暴力指用堆维护每......