[NOI2010] 超级钢琴 题解
[NOI2010] 超级钢琴 题解
说点闲话
原本不想写这个题解的
但是看到我的代码居然长度为2048B->刚好2KiB,然后还跟题号相同QAQ
题目翻译
给你一段序列,求出其中从第
思路解析
首先可以想到一个简单的暴力,对于每一个区间开头
但是这个暴力时间复杂度太大了,是
然后将所有的五元组塞入一个堆里面,从堆中取
关于Debug
我做这道题的时候挺顺的,交的时候一遍就过了。
可能比较需要注意的是:
1)初始塞五元组的时候,防止
2)分裂的时候不要让新的五元组的
3)线段树不要写错了(我就是写错了线段树没过样例QAQ)
关于代码
#include <cstdio>
#include <cstring>
#include <queue>
#define MAXN 500010
using namespace std;
int OLine[MAXN],Sum[MAXN],Total=0,RetP=0,RetV=0,n,k,l,r;
long long Ans=0;
struct O{
int Value,StLeft,Left,Right,Position;
};
bool operator<(O a,O b){
return a.Value<b.Value;
}
priority_queue <O> Q;
struct N{
int Left,Right;
int Value,Pos;
int LeftN,RightN;
}Node[MAXN<<2];
void Build(int Left,int Right){
Total++;
Node[Total].Left=Left;
Node[Total].Right=Right;
if(Left==Right){Node[Total].Value=Sum[Left]; Node[Total].Pos=Left; return;}
int Now=Total,Mid=(Left+Right)>>1;
Node[Now].LeftN=Total+1;Build(Left,Mid);
Node[Now].RightN=Total+1;Build(Mid+1,Right);
Node[Now].Value=Node[Node[Now].LeftN].Value,Node[Now].Pos=Node[Node[Now].LeftN].Pos;
if(Node[Node[Now].RightN].Value>Node[Now].Value){
Node[Now].Value=Node[Node[Now].RightN].Value,Node[Now].Pos=Node[Node[Now].RightN].Pos;
}
}
void Query(int Now,int Left,int Right){
if(Node[Now].Left>=Left&&Node[Now].Right<=Right){if(Node[Now].Value>RetV){RetV=Node[Now].Value;RetP=Node[Now].Pos;}return;}
else if(Node[Now].Left>Right||Node[Now].Right<Left){return;}
else{
Query(Node[Now].LeftN,Left,Right);
Query(Node[Now].RightN,Left,Right);
}
}
O Make(int StL,int Left,int Right){
O Ret;
Ret.StLeft=StL;
Ret.Left=Left;
Ret.Right=Right;
RetP=-1<<30,RetV=-1<<30;
Query(1,Left,Right);
Ret.Position=RetP;
Ret.Value=RetV;
Ret.Value-=Sum[StL-1];
return Ret;
}
int main(){
scanf("%d%d%d%d",&n,&k,&l,&r);
Sum[0]=0;
for(int i=1;i<=n;i++){
scanf("%d",&OLine[i]);
Sum[i]=Sum[i-1]+OLine[i];
}
Build(1,n);
for(int i=1;i<=n;i++){
int LL,RR;
if(i+l-1<=n) LL=i+l-1;
else{break;}
if(i+r-1<=n) RR=i+r-1;
else RR=n;
Q.push(Make(i,LL,RR));
}
while(k--){
Ans+=Q.top().Value;
int P=Q.top().Position;
int LL=Q.top().Left,RR=Q.top().Right,STLL=Q.top().StLeft;
Q.pop();
if(P!=LL) Q.push(Make(STLL,LL,P-1));
if(P!=RR) Q.push(Make(STLL,P+1,RR));
}
printf("%lld",Ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】