poj2828

题意:人们一个一个的来排队并插队,按人到来的顺序给出每个人插队的位置(插在第几个人后面),并告知每个人的id号,输出最终队伍的情况。

分析:可以用线段树,从最后来的一个人开始向来得更早的人遍历,这样pos(插在第几个人后面)的意义就变成了,前面有多少个空位。线段树上每个节点中存储的是当前时刻,该区间有多少空位。

View Code
#include <iostream>
#include
<cstdlib>
#include
<cstring>
#include
<cstdio>
usingnamespace std;

#define maxn 200005

struct Node
{
Node
*pleft, *pright;
int num, l, r, pos;
}tree[maxn
*10];

struct Item
{
int pos, val;
}f[maxn];

int n, ncount, ans[maxn];

void input()
{
for (int i =0; i < n; i++)
scanf(
"%d%d", &f[i].pos, &f[i].val);
}

void buildtree(Node *proot, int l, int r)
{
proot
->num = r - l +1;
proot
->l = l;
proot
->r = r;
if (l == r)
{
proot
->pos = l;
return;
}
ncount
++;
proot
->pleft = tree + ncount;
ncount
++;
proot
->pright = tree + ncount;
int mid = (l + r) /2;
buildtree(proot
->pleft, l, mid);
buildtree(proot
->pright, mid +1, r);
}

void ins(Node *proot, int num, int val)
{
proot
->num--;
if (proot->l == proot->r)
{
ans[proot
->pos] = val;
return;
}
if (num >= proot->pleft->num)
ins(proot
->pright, num - proot->pleft->num, val);
else
ins(proot
->pleft, num, val);
}

void work()
{
for (int i = n -1; i >=0; i--)
ins(tree, f[i].pos, f[i].val);
printf(
"%d", ans[0]);
for (int i =1; i < n; i++)
printf(
" %d", ans[i]);
printf(
"\n");
}

int main()
{
//freopen("D:\\t.txt", "r", stdin);
while (scanf("%d", &n) != EOF )
{
input();
buildtree(tree,
0, n -1);
work();
}
return0;
}
原文地址:https://www.cnblogs.com/rainydays/p/1989476.html