POJ2828 Buy Tickets

有N个人排队,每一个人都有一个val来对应,每一个后来人都会插入当前队伍的某一个位置pos。要求把队伍最后的状态输出。

倒序插入,线段树单点更新,从头到尾输出线段树的状态

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=2e6+14;
struct men {
    int pos;
    int val;
}Men[maxn*4];
int a[maxn];
struct node {
    int l;
    int r;
    int sum;
}segTree[maxn*4]; 
void build (int i,int l,int r) {
    segTree[i].l=l;
    segTree[i].r=r;
    segTree[i].sum=0;
    if (l==r) return;
    int mid=(segTree[i].l+segTree[i].r)>>1;
    build(i<<1,l,mid);
    build(i<<1|1,mid+1,r);
}
void add (int i,int k,int val) {
    if (segTree[i].l==segTree[i].r) {
        segTree[i].sum++;
        a[segTree[i].l]=val;
        return;
    }
    int mid=(segTree[i].l+segTree[i].r)>>1;
    int tmp=mid-segTree[i].l+1-segTree[i<<1].sum;
    if (tmp>k) add(i<<1,k,val);
    else add(i<<1|1,k-tmp,val);
    segTree[i].sum=segTree[i<<1].sum+segTree[i<<1|1].sum;
}
int main () {
    int n;
    while (~scanf("%d",&n)) {
        build(1,1,n);
        for (int i=1;i<=n;i++) {
            scanf ("%d %d",&Men[i].pos,&Men[i].val);
        }
        for (int i=n;i>=1;i--) {
            add(1,Men[i].pos,Men[i].val);
        }
        for (int i=1;i<=n;i++) {
            if (i!=1) printf (" ");
            printf ("%d",a[i]);
        }
        printf ("\n");
    }
    return 0;
}

 

posted @ 2020-02-17 18:42  zlc0405  阅读(81)  评论(0编辑  收藏  举报