POJ - 2828 Buy Tickets(线段树单点更新)

Posted fht-litost

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ - 2828 Buy Tickets(线段树单点更新)相关的知识,希望对你有一定的参考价值。

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

题意

排队买票,依次给出当前人要插队的位置,每个人有个编号,然后问你最后整个的序列是什么?

分析

最后一个人的要插入的位置是确定的,所以逆序遍历,线段树结点存储的是当前区域的空位置数量。我们就可以倒着来插,最后一个固定后,如果倒数第二个插入的位置小于当前的空格数,那么就往前插到序号上,否则往后插,往后的话序号需要减去当前这个数左边的空位数。因为左右都是从0位置开始标记的,因此结构体里需要维持节点左右边的空位个数,(当前插队序号小于左边空位插左边,大于的话插右边,但是需要需要减去左边空位)。因为右边也是从0位置开始算起的。

#include<iostream>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<cstdio>
#include<algorithm>
#include<map>
#include<set>
#define rep(i,e) for(int i=0;i<(e);i++)
#define rep1(i,e) for(int i=1;i<=(e);i++)
#define repx(i,x,e) for(int i=(x);i<=(e);i++)
#define X first
#define Y second
#define PB push_back
#define MP make_pair
#define mset(var,val) memset(var,val,sizeof(var))
#define scd(a) scanf("%d",&a)
#define scdd(a,b) scanf("%d%d",&a,&b)
#define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define pd(a) printf("%d
",a)
#define scl(a) scanf("%lld",&a)
#define scll(a,b) scanf("%lld%lld",&a,&b)
#define sclll(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
#define IOS ios::sync_with_stdio(false);cin.tie(0)
#define lc idx<<1
#define rc idx<<1|1
#define lson l,mid,lc
#define rson mid+1,r,rc
using namespace std;
typedef long long ll;
template <class T>
void test(T a){cout<<a<<endl;}
template <class T,class T2>
void test(T a,T2 b){cout<<a<<" "<<b<<endl;}
template <class T,class T2,class T3>
void test(T a,T2 b,T3 c){cout<<a<<" "<<b<<" "<<c<<endl;}
const int N = 1e6+10;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3fll;
const ll mod = 1000000007;
int T;
void testcase(){
    printf("Case #%d:
",++T);
}
const int MAXN = 2e5+10;
const int MAXM = 30;
struct node{
    int l,r,w;
}tree[MAXN<<2];
int n;
int ans[MAXN],val[MAXN],pos[MAXN];
void build(int l,int r,int idx){
    tree[idx].l=l,tree[idx].r=r;
//    tree[idx].w=r-l+1;
    if(l==r){
        tree[idx].w=1;
        return;
    }
    int mid = (l+r)>>1;
    build(lson);
    build(rson);
    tree[idx].w=tree[lc].w+tree[rc].w;
}
void update(int pos,int val,int idx){
    if(tree[idx].l==tree[idx].r){
        tree[idx].w--;
        ans[tree[idx].l]=val;
        return;
    }
    if(pos<=tree[lc].w) update(pos,val,lc);
    else update(pos-tree[lc].w,val,rc);
    tree[idx].w=tree[lc].w+tree[rc].w;
}
int main() {
#ifdef LOCAL
    freopen("in.txt","r",stdin);
#endif // LOCAL
    while(~scd(n)){
        for(int i=1;i<=n;i++) scdd(pos[i],val[i]);
        build(1,n,1);
        for(int i=n;i>0;i--) update(pos[i]+1,val[i],1);
        for(int i=1;i<n;i++) printf("%d ",ans[i]);
        printf("%d
",ans[n]);
    }
    return 0;
}

 

以上是关于POJ - 2828 Buy Tickets(线段树单点更新)的主要内容,如果未能解决你的问题,请参考以下文章

POJ 2828Buy Tickets(线段树的单点维护)

POJ 2828 Buy Tickets(线段树单点)

POJ - 2828 Buy Tickets(线段树单点更新)

POJ 2828 Buy Tickets (线段树 or 树状数组+二分)

POJ2828Buy Tickets(线段树)

Buy Tickets POJ - 2828 思维+线段树