[NOI2010] 超级钢琴 - 贪心,堆,ST表
2024-10-08 09:58:51
这也算是第K大问题的套路题了(虽然我一开始还想了个假算法),大体想法就是先弄出最优的一批解,然后每次从中提出一个最优解并转移到一个次优解,用优先队列维护这个过程即可。
类似的问题很多,放在序列上的,放在图上的,改天可以考虑补个专题。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1000005;
int a[N],s[N],st[N][20],stp[N][20],n,k,L,R;
int query(int l,int r)
{
int lg=log2(r-l+1);
int tmp = max(st[l][lg],st[r-(1<<lg)+1][lg]);
if(tmp==st[l][lg]) return stp[l][lg];
else return stp[r-(1<<lg)+1][lg];
}
inline int eval(int o,int l,int r)
{
return s[query(l,r)]-s[o-1];
}
struct Item
{
int o,l,r;
bool operator < (const Item &b) const
{
return eval(o,l,r) < eval(b.o,b.l,b.r);
}
};
Item gen(int o,int l,int r)
{
Item tmp;
tmp.o=o;
tmp.l=l;
tmp.r=r;
return tmp;
}
priority_queue <Item> q;
int ans = 0;
signed main()
{
cin>>n>>k>>L>>R;
for(int i=1;i<=n;i++)
{
cin>>a[i];
s[i]=s[i-1]+a[i];
st[i][0]=s[i];
stp[i][0]=i;
}
for(int j=1;j<=19;j++)
for(int i=1;i+(1<<j)-1<=n;i++)
{
st[i][j]=max(st[i][j-1],st[i+(1<<(j-1))][j-1]);
if(st[i][j]==st[i][j-1])
stp[i][j]=stp[i][j-1];
else
stp[i][j]=stp[i+(1<<(j-1))][j-1];
}
for(int i=1;i+L-1<=n;i++)
{
q.push(gen(i,i+L-1,min(i+R-1,n)));
}
while(k--)
{
Item p=q.top();
q.pop();
int tans = eval(p.o,p.l,p.r);
ans += tans;
int mid = query(p.l,p.r);
if(mid!=p.l)
{
Item x=p;
x.r=mid-1;
if(x.r>=x.l) q.push(x);
}
if(mid!=p.r)
{
Item x=p;
x.l=mid+1;
if(x.r>=x.l) q.push(x);
}
}
cout<<ans<<endl;
}
最新文章
- TechEmpower 13轮测试中的ASP.NET Core性能测试
- (DNS被劫持所导致的)QQ音乐与视频网页打开很慢的解决方法
- S3C2440上RTC时钟驱动开发实例讲解(转载)
- 让编辑器支持word的复制黏贴,支持截屏的黏贴
- 伪静态URLRewrite学习笔记
- javaIO整理
- How to display SSRS report based on customer/Vendor specific language [AX2012]
- python多线程,多进程
- Python中的输出
- c#读取Excel数据到Gridview
- eclipse使用javaFX写一个HelloWorkld
- pytorch怎么抽取中间的特征或者梯度
- JMeter&#160;java.net.SocketException:Operationnotsupported:connect解决方案
- Quartz.NET的简单任务管理类
- SQL记录-小表join大表查询例子
- jQuery插件初级练习2
- 2018.10.05 NOIP模拟 上升序列(状压dp)
- 微信公众号第三方平台生成自定义菜单提示 获取";access_token失败";
- MFC CreateWindow介绍
- 饿了么 PostgreSQL 优化之旅