超级钢琴 BZOJ 2006
超级钢琴
【问题描述】
【输入格式】
【输出格式】
只有一个整数,表示乐曲美妙度的最大值。
【样例输入】
4 3 2 3
3
2
-6
8
【样例输出】
11
【样例说明】
共有5种不同的超级和弦:
音符1 ~ 2,美妙度为3 + 2 = 5
音符2 ~ 3,美妙度为2 + (-6) = -4
音符3 ~ 4,美妙度为(-6) + 8 = 2
音符1 ~ 3,美妙度为3 + 2 + (-6) = -1
音符2 ~ 4,美妙度为2 + (-6) + 8 = 4
最优方案为:乐曲由和弦1,和弦3,和弦5组成,美妙度为5 + 2 + 4 = 11。
题解:
设三元组 (l, r, i) 表示以 i 为开始,以某个 j (l<j<r) 为结束组成的和弦能到达的最大美妙度
我们记录前缀和 sum,对于以 i 为开始的前缀, sum[i-1] 是确定的,即只要得到最大的 sum[j] (l<j<r),最大美妙度为 sum[j]-sum[i-1]
即查询 l 到 r 之间的最大的 sum
一开始我们将所有 (i + L - 1, i + R - 1, i) 加入大根堆中,保证和弦长度在 L 到 R 之间
每次取出堆顶的标号,记为s
把这个三元组 (l, r, i) 拆成 (l, s - 1, i) 和 (s + 1, r, i) 两个三元组,再次加入堆中(因为这两个答案也有可能比其他 i 的答案优)
重复这个操作,直到取了k次
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 5e5 + ;
int logn;
int n, k;
int lg[maxn], bin[];
int sum[maxn];
inline void Scan(int &x)
{
char c;
bool o = false;
while(!isdigit(c = getchar())) o = (c != '-') ? o : true;
x = c - '';
while(isdigit(c = getchar())) x = x * + c - '';
if(o) x = -x;
}
struct rmq
{
int i, v;
};
rmq maxx[][maxn];
struct interval
{
int l, r, a, b, v;
};
inline bool operator < (interval a, interval b)
{
return a.v < b.v;
}
priority_queue <interval> q;
inline rmq Max(rmq a, rmq b)
{
return (a.v > b.v) ? a : b;
}
inline bool operator < (rmq a, rmq b)
{
return a.v < b.v;
}
inline void Rmq()
{
for(int i = ; i <= logn; ++i)
for(int j = ; j <= n; ++j)
{
if(j + bin[i] - > n) continue;
int k = j + bin[i - ];
maxx[i][j] = max(maxx[i - ][j], maxx[i - ][k]);
}
}
inline int Query(int l, int r)
{
if(l > r) return -;
int len = lg[r - l + ];
return Max(maxx[len][l], maxx[len][r - bin[len] + ]).i;
}
int main()
{
int l, r;
Scan(n), Scan(k), Scan(l), Scan(r);
logn = log2(n);
bin[] = ;
for(int i = ; i <= logn; ++i) bin[i] = bin[i - ] << , lg[bin[i]] = ;
for(int i = ; i <= n; ++i) lg[i] += lg[i - ];
for(int i = ; i <= n; ++i)
{
Scan(sum[i]);
sum[i] += sum[i - ];
maxx[][i] = (rmq) {i, sum[i]};
}
Rmq();
interval s;
int x, u, v, a, b;
for(int i = ; i <= n - l + ; ++i)
{
int a = i + l - , b = min(n, i + r - );
x = Query(a, b);
s = (interval) {a, b, i, x, sum[x] - sum[i - ]};
q.push(s);
}
long long ans = ;
while(k--)
{
s = q.top();
q.pop();
ans += s.v;
u = Query(s.l, s.b - );
v = Query(s.b + , s.r);
if(u > ) q.push((interval) {s.l, s.b - , s.a, u, sum[u] - sum[s.a - ]});
if(v > ) q.push((interval) {s.b + , s.r, s.a, v, sum[v] - sum[s.a - ]});
}
printf("%lld", ans);
}
超级钢琴 BZOJ 2006的更多相关文章
- 2006: [NOI2010]超级钢琴 - BZOJ
Description小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度为 ...
- [BZOJ 2006] [NOI 2010]超级钢琴(贪心+ST表+堆)
[BZOJ 2006] [NOI 2010]超级钢琴(贪心+ST表+堆) 题面 给出一个长度为n的序列,选k段长度在L到R之间的区间,一个区间的值等于区间内所有元素之的和,使得k个区间的值之和最大.区 ...
- BZOJ 2006: [NOI2010]超级钢琴
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 2613 Solved: 1297[Submit][Statu ...
- Bzoj 2006: [NOI2010]超级钢琴 堆,ST表
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 2222 Solved: 1082[Submit][Statu ...
- BZOJ 2006: [NOI2010]超级钢琴( RMQ + 堆 )
取最大的K个, 用堆和RMQ来加速... ----------------------------------------------------------------- #include<c ...
- 【BZOJ 2006】2006: [NOI2010]超级钢琴(RMQ+优先队列)
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 2792 Solved: 1388 Description 小 ...
- 洛谷 P2048 BZOJ 2006 [NOI2010]超级钢琴
题目描述 小Z是一个小有名气的钢琴家,最近C博士送给了小Z一架超级钢琴,小Z希望能够用这架钢琴创作出世界上最美妙的音乐. 这架超级钢琴可以弹奏出n个音符,编号为1至n.第i个音符的美妙度为Ai,其中A ...
- bzoj千题计划162:bzoj2006: [NOI2010]超级钢琴
http://www.lydsy.com/JudgeOnline/problem.php?id=2006 输出最大的k个 sum[r]-sum[l-1] (L<=r-l+1<=R) 之和 ...
- 【BZOJ-2006】超级钢琴 ST表 + 堆 (一类经典问题)
2006: [NOI2010]超级钢琴 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 2473 Solved: 1211[Submit][Statu ...
随机推荐
- 将unity3d项目嵌入到Android App中使用
创建一个新的AndroidStudio app项目. 1.添加库文件:拷贝unity安装目录下的库文件:Unity\Editor\Data\PlaybackEngines\AndroidPlayer\ ...
- sqlite3 数据库使用
首先,通过官网下载sqlite3.h和sqlite3.c两个文件,用于调用里面的api函数操作数据库. 这里也提供链接地址下载:http://pan.baidu.com/s/1qWzjqPY 其中里面 ...
- Python学习记录4(语句)
赋值语句 序列解包 条件语句 语句块 布尔变量 条件执行和if语句 条件运算符 循环 while语句 for循环 迭代工具 跳出循环 break continue while truebreak语句 ...
- Unity基础-编辑器
编辑器 Special Folders Hidden Folder(start with .) Standard Assets:第一批加载的文件 Editor:只在编辑下才能使用, Plugins R ...
- poj 1995 快速幂
题意:给出A1,…,AH,B1,…,BH以及M,求(A1^B1+A2^B2+ … +AH^BH)mod M. 思路:快速幂 实例 3^11 11=2^0+2^1+2^3 => 3^1*3 ...
- BZOJ 2217: [Poi2011]Lollipop
若sum可行 sum-2一定可行 序列和为ans 找出和ans奇偶性不同的最大的ans,即最靠左或最靠右的1的位置 更新答案 有spj #include<cstdio> using nam ...
- day08 多线程socket 编程,tcp粘包处理
复习下socket 编程的步骤: 服务端: 1 声明socket 实例 server = socket.socket() #括号里不写 默认地址簇使用AF_INET 即 IPv4 ...
- mysql 索引和查询优化
对于任何DBMS,索引都是进行优化的最主要的因素.对于少量的数据,没有合适的索引影响不是很大,但是,当随着数据量的增加,性能会急剧下降.如果对多列进行索引(组合索引),列的顺序非常重要,MySQL仅能 ...
- rsa Round #71 (Div. 2 only)
Replace A Time limit: 1000 msMemory limit: 256 MB You are given a string SS containing only letter ...
- Pandas对多列进行升降序排列
df = pd.DataFrame(rows, columns = ["llx", "lly", "urx", "ury" ...