您的位置:首页 > 其它

poj 2828 Buy Tickets (线段树sum)

2012-08-25 11:38 423 查看
http://poj.org/problem?id=2828

(1)注意到,最后插队的人的位置是一定的,前一个人的位置的最终稳定取决于后面的所有人。为了避免插入一个新数时要挪出位置的尴尬,更为效率考虑,

   可以从后往前插入树中(注意谁决定谁的关系的使用)。

(2)小细节:

      1) 0~n-1 而不是 1~n;

2)先输入,再更新(分开来);

3)希望今后的小错误可以尽快找出,线段树的写法虽然懂,但小错误最伤不起(很幼稚的类型,却很长时间才发现);

      4)几乎所有的线段树都是求和、最值,但是各种包装下没能看清本质,还要多练手(题库里还有大约40题)。

(3)对于每个插队的人(倒着数),要留有pos[i]个空位,自己占有第pos[i]+1个空位:

update(pos[i]+1, val[i], 0, n, 1);


具体代码:

View Code

#include<stdio.h>
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
const int maxn=201000;
int n;
int sum[maxn<<2];
int pos[maxn], val[maxn], ans[maxn];
void pushup(int rt)
{
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void build(int l, int r, int rt)
{
if(l==r)
{
sum[rt]=1;
return ;
}
int m=l+r>>1;
build(lson);
build(rson);
pushup(rt);
}
void update(int pos, int val, int l, int r, int rt)
{
if(l==r)
{
sum[rt]=0;
ans[l]=val;
return ;
}
int m=l+r>>1;
if(sum[rt<<1]>=pos) update(pos, val, lson);
else update(pos-sum[rt<<1], val, rson);
pushup(rt);
}
int main()
{
int i, j, k;
while(scanf("%d", &n)!=EOF)
{
build(0, n, 1);
for(i=0;i<n;i++) scanf("%d%d", &pos[i], &val[i]);
for(i=n-1;i>=0;i--)
{
update(pos[i]+1, val[i], 0, n, 1);
}
printf("%d", ans[0]);
for(i=1;i<n;i++)
printf(" %d", ans[i]);
printf("\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: