题面
题解
勘误:新的休息点a需要满足的条件2为那一部分小于等于ans
代码
(100pts)
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
inline int gi() {
register int data = 0, w = 1;
register char ch = 0;
while (!isdigit(ch) && ch != '-') ch = getchar();
if (ch == '-') w = -1, ch = getchar();
while (isdigit(ch)) data = 10 * data + ch - '0', ch = getchar();
return w * data;
}
const int MAX_N = 5e5 + 5;
int N, M, a[MAX_N], sum[MAX_N], cnt[MAX_N];
struct Node { int l, r, v; } Line[MAX_N << 1]; int tot = 0;
struct deque {
int head, tail, len;
deque() { head = tail = len = 0; }
bool empty() { return !len; }
int newNode(int l, int r, int v) { Line[++tot] = (Node){ l, r, v }; return tot; }
int front() { return Line[head].v; }
int back() { return Line[tail].v; }
void pop_back() { tail = Line[tail].l, len--; }
void pop_front() { head = Line[head].r, len--; }
void push_back(int v) {
if (!len) head = tail = newNode(0, 0, v);
else Line[tail].r = newNode(tail, 0, v), tail = Line[tail].r;
len++;
}
void push(int v) {
while (len && a[back()] > a[v]) pop_back();
push_back(v);
}
} Q[MAX_N << 1], Qu[MAX_N << 1], *q = Q + MAX_N, *qu = Qu + MAX_N;
#define min(x, y) ((a[x]) < (a[y]) ? (x) : (y))
int main() {
#ifndef ONLINE_JUDGE
freopen("cpp.in", "r", stdin);
#endif
N = gi(), M = gi();
for (int i = 1; i <= N; i++) a[i] = gi(), sum[i] = gi(), sum[i] = sum[i] ? 1 : -1;
for (int i = N - 1; i >= 1; i--) sum[i] += sum[i + 1];
for (int i = N; i >= 1; i--) cnt[i] = cnt[i + 1] + (!sum[i]);
int S = sum[1], d = S ? (abs(S) - 1) / M + 1 : cnt[1] < M;
cnt[N + 1] = -1;
if (!d) {
for (int i = 1, j = 2; i < M; i++) {
for (; cnt[j + 1] >= M - i; j++) if (!sum[j + 1]) q[0].push(j);
printf("%d ", a[q[0].front()]);
q[0].pop_front();
}
} else {
for (int i = 2; i <= N; i++) qu[sum[i]].push_back(i - 1);
int lst = 0;
a[N + 1] = N + 1;
for (int i = 1; i < M; i++) {
int ans = N + 1;
for (int j = sum[lst + 1] - d; j <= sum[lst + 1] + d; j++) {
if (ceil(1.0 * abs(j) / (M - i)) > d) continue;
for (; !qu[j].empty() && N - qu[j].front() >= M - i; qu[j].pop_front())
if (qu[j].front() > lst) q[j].push(qu[j].front());
for (; !q[j].empty() && q[j].front() <= lst; q[j].pop_front()) ;
if (!q[j].empty()) ans = min(ans, q[j].front());
}
lst = ans, printf("%d ", a[ans]);
}
}
printf("%d
", a[N]);
return 0;
}