题意:一家店门口有n个人在排队,按顺序给出每个人要站在第几个人的后面,假设店是第0个人,给每个人一个代号,问最后代号的顺序是什么。
题解:因为后面的人有可能占前面的人的位置,所以倒着来,每个人位置的含义变成了给前面留多少个空位,线段树实现。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 200005;
int n, s[N << 2], p[N], v[N], res[N];
void pushup(int k) {
s[k] = s[k * 2] + s[k * 2 + 1];
}
void build(int k, int left, int right) {
if (left == right) {
s[k] = 1;
return;
}
int mid = (left + right) / 2;
build(k * 2, left, mid);
build(k * 2 + 1, mid + 1, right);
pushup(k);
}
void modify(int k, int left, int right, int pos, int val) {
if (left == right) {
res[left] = val;
s[k] = 0;
return;
}
int mid = (left + right) / 2;
if (pos <= s[k * 2])
modify(k * 2, left, mid, pos, val);
else
modify(k * 2 + 1, mid + 1, right, pos - s[k * 2], val);
pushup(k);
}
int main() {
while (scanf("%d", &n) == 1) {
build(1, 1, n);
for (int i = 1; i <= n; i++)
scanf("%d%d", &p[i], &v[i]);
for (int i = n; i >= 1; i--)
modify(1, 1, n, p[i] + 1, v[i]);
printf("%d", res[1]);
for (int i = 2; i <= n; i++)
printf(" %d", res[i]);
printf("\n");
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-18 22:14:41