现在的位置: 首页 > 综合 > 正文

poj2828 Buy Tickets

2018年04月21日 ⁄ 综合 ⁄ 共 856字 ⁄ 字号 评论关闭

给N 个人 给出位置 每个人的价值 然后求出最后的价值的顺序

a1 a2 a3 a4 如果 后面的n位置和前面的人位置相等 那么前面的人要后移一位

这样只要倒着处理就好 从最后一位开始更新

建树时父节点存的是子节点可以放多少人 所以 r - l + 1

这个可以画图理解一下

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
#define Lson l,m,rt<<1
#define Rson m+1,r,rt<<1|1
int const MAXN = 200010;
int ans[MAXN];
struct Tree{
    int l,r;
    int s,v;
}tree[MAXN<<2];
struct Point{
    int pos,v;
}p[MAXN];
void Build(int l,int r,int rt){
    tree[rt].s = r - l + 1;
    if(l == r) return ;
    int m = (l + r)>>1;
    Build(Lson);
    Build(Rson);
}
void Update(int c,int x,int l,int r,int rt){
    tree[rt].s--;
    if(l == r){
        ans[l] = c;
        return ;
    }
    int m = (l + r)>>1;
    if(tree[rt<<1].s >= x)Update(c,x,Lson);
    else Update(c,x - tree[rt<<1].s,Rson);
}
int main(){
    int n;
    while(~scanf("%d",&n)){
        Build(1,n,1);
        memset(ans,0,sizeof(ans));
        for(int i = 0;i < n;i++){
            scanf("%d%d",&p[i].pos,&p[i].v);
        }
        for(int i = n - 1;i >= 0;i--){
            Update(p[i].v,p[i].pos + 1,1,n,1);
        }
        for(int i = 1;i <= n - 1;i++){
            printf("%d ",ans[i]);
        }
        printf("%d\n",ans[n]);
    }
    return 0;
}

【上篇】
【下篇】

抱歉!评论已关闭.