BZOJ 2006 [NOI2010] super piano

DescriptionDescription
have nn notes, numbered from 11 to nn. Ii wonderful degree of notes is AiAi.

We need to find a song chords super kk segment, the number of each successive note of xx meet L≤x≤RL≤x≤R, seeking the maximum degree of wonderful music.

SolutionSolution
greedy + heap + RMQ

First of all you can see, each super chords are continuous, beauty of all the wonderful degrees during this period and. It is contemplated that each solution interval and obviously does not pay, so consider using the prefix and.

Consider violence, we need to meet the conditions of all the fields to row out of a sequence, but it is unthinkable. So consider the use of greedy idea to solve this problem.

First think pretreatment. We define MAX (o, l, r) = max {sum (o) -sum (t-1) | l≤t≤r} MAX (o, l, r) = max {sum (o) -sum (t -1) | l≤t≤r}, i.e., the right end point to oo, left endpoint range is [l, r] [l, r] is the maximum sub-segment. Seek sum () sum () on the use of the prefix and said earlier. As can be seen, oo position is fixed. So sum (o) sum (o) is fixed. So we ask the maximum value, as long as the sum (t-1) sum (t-1) can be a minimum. That required sum (t-1) sum (t-1) in [l, r] [l, r] the minimum, that how quickly obtain the maximum it? Obviously, this is not RMQRMQ live it. For RMQRMQ not familiar with can refer to this. Of course, when the specific calculation of the lower bound ll have to see if less than 11.

Then you think how greedy. We can always choose the best sub-segments, this is obviously the result of the election kk times we want, then how to find the optimal solution it? The solution used to deposit into the heap, each element is the top of the heap of the optimal solution.

Consider a triple (o, l, r) (o, l, r) expressed in the right end point oo, the left end point selection interval is [l, r] [l, r] in the case, I used a structstruct to represent the triples, but often virtually every situation requires an optimal solution tt additional records of this case, this does not trouble to knock a constructor structstruct inside it.

We assume that the maximum current is triples (o, l, r) (o, l, r). Optimum position is tt. ansans cumulative contribution of the triplet. Tt has been selected since, for this OO, tt has been selected can not be repeated, but the optimal solution may also be present in the range of about tt ends, the so extracted (o, l, r) (o, l, r) after to avoid repetition without losing other better solution, we still want (o, l, t-1) (o, l, t-1), (o, t + 1, r) (o, t + 1 , r) go back into the heap. Obviously, before discharge back should guarantee the existence range, i.e. l ​​= tl = t or tr = t r = where Laid sentence to be performed.

Finally, when implemented, but not least, RMQRMQ originally recorded inside the array is the value of the optimal solution, but we query interval maximum value when the query is the location of the optimal solution. So array position is kept inside the optimal solution, to special treatment.

CodeCode
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#define MAXN 500005
#define LOG 20
#define max(x, y) ((x) > (y) ? (x) : (y))
#define min(x, y) ((x) < (y) ? (x) : (y))
long long sum[MAXN], ST[MAXN][LOG];
namespace RMQ {
int calc(int x, int y) {
return sum[x - 1] < sum[y - 1] ? x : y;
}
void init(int n) {
for (int i = 1; i <= n; i++) ST[i][0] = i;
for (int j = 1; (1 << j) <= n; j++)
for (int i = 1; i + (1 << j) - 1 <= n; i++)
ST[i][j] = calc(ST[i][j - 1], ST[i + (1 << (j - 1))][j - 1]);
}
int query(int l, int r) {
int k = log2(r - l + 1);
return calc(ST[l][k], ST[r - (1 << k) + 1][k]);
}
}
struct element {
int o, l, r, t;
element() {}
element(int o, int l, int r) : o(o), l(l), r(r), t(RMQ::query(l, r)) {}
friend bool operator < (const element& a, const element& b) {
return sum[a.o] - sum[a.t - 1] < sum[b.o] - sum[b.t - 1];
}
};
std::priority_queue< element > Q;
int main() {
int n, k, L, R;
scanf("%d%d%d%d", &n, &k, &L, &R);
for (int i = 1; i <= n; i++) {
scanf("%lld", &sum[i]);
sum[i] += sum[i - 1];
}
RMQ::init(n);
for (int i = L; i <= n; i++)
Q.push (Element (I, max (. 1, I - R & lt +. 1), I -. 1 + L));
Long Long ANS = 0;
the while (K--) {
int Q.top = O () O. ..., L = Q.top () L, R & lt Q.top = () R & lt, Q.top = T () T;
Q.pop ();
ANS = SUM + [O] - SUM [T -. 1 ];
IF (L = T!) Q.push (Element (O, L, T -. 1));
IF (! T = R & lt) Q.push (Element (O,. 1 + T, R & lt));
}
the printf ( "% LLD \ the n-", ANS);
return 0;
}
----------------
copyright: original article is CSDN blogger "Nekroz_", and follow CC 4.0 BY -SA copyright agreement, reproduced, please attach the original source link and this statement.
Original link: https: //blog.csdn.net/diogenes_/article/details/80820571

Guess you like

Origin www.cnblogs.com/aprincess/p/11621529.html