poj 2828 but tickets(线段树+逆序遍历)

来源:互联网 发布:java.util string 编辑:程序博客网 时间:2024/04/30 05:05

题目:http://poj.org/problem?id=2828

题目大意是指有n个人需要插队,第i个人插队的位置是posi,价值是Vali(插队居然还有价值= =)

值得注意的是,当第i位置原本有人的情况下,那个人会被往后退一位,以此类推

所以这题目只要逆序遍历 从后往前插,pos表示他前面有多少的空位,叶子结点存他的val 这样就转化到线段树上 然后就简单了。

(需要注意的是,这题目输出控制最后一个数后面不带‘ ’直接‘\n’)


//从后往前插,pos表示他前面有多少的空位,叶子结点存他的val 这样就转化到线段树上 然后就简单了#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>#include <queue>#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define maxn 222222int tree[maxn<<2];int pos[maxn],val[maxn],seg[maxn];int num;void build(int l,int r,int rt){    int m=(l+r)>>1;    tree[rt]=r-l+1;    if(l==r)        return ;    build(lson);    build(rson);}void update(int p,int l,int r,int rt){    int m=(l+r)>>1;    tree[rt]--;    if(l==r)    {        num=l;        return ;    }        if(tree[rt<<1]>=p)        {            update(p,lson);        }        else        {            p-=tree[rt<<1];            update(p,rson);        }}int main(){    freopen("in.txt","r",stdin);    int n;    while(scanf("%d",&n)!=EOF)    {        build(1,n,1);        for(int i=1;i<=n;i++)        {            scanf("%d%d",&pos[i],&val[i]);        }        for(int i=n;i>=1;i--)        {            update(pos[i]+1,1,n,1);            seg[num]=val[i];        }        for(int i=1;i<=n;i++)        {            if(i==n)            {                printf("%d",seg[i]);                break;            }            printf("%d ",seg[i]);        }        printf("\n");    }    return 0;}




0 0
原创粉丝点击