首页 > 其他 > 详细

POJ2828 Buy Tickets (线段树)

时间:2020-02-19 15:37:37      阅读:53      评论:0      收藏:0      [点我收藏+]

这道题我们发现如果从前面往后插,我们并不能得到正确答案,因为位置一直在变化,

所以我们考虑从后往前插,最后一个数的位置肯定是正确的,接下来的树根据这个数的位置而改变

这里用到了一个权值线段树的一些想法,根据节点的大小来选择插哪边

技术分享图片
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map> 
#include<vector> 
using namespace std;
typedef  long long ll;
const int N=5e5+10;
const int inf=0x3f3f3f3f;
struct qi{
    int x;
    int num;
}q[N];
struct node{
    int l,r;
    int size;
    int num;
}tr[N<<2];
int ans[N];
void pushup(int u){
    tr[u].size=tr[u<<1].size+tr[u<<1|1].size;
}
void build(int u,int l,int r){
    if(l==r){
        tr[u]={l,r,1};
    }
    else{
        tr[u]={l,r};
        int mid=l+r>>1;
        build(u<<1,l,mid);
        build(u<<1|1,mid+1,r);
        pushup(u);
    }
}
void modify(int u,int pos,int x){
    if(tr[u].l==tr[u].r){
        ans[tr[u].l]=x;
        tr[u].size--;
        return ;
    }
    if(pos<=tr[u<<1].size)
    modify(u<<1,pos,x);
    else
    modify(u<<1|1,pos-tr[u<<1].size,x);
    pushup(u);
}
int main(){
    int n;
    while(cin>>n){
        int i;
        build(1,1,n);
        memset(ans,0,sizeof ans);
        for(i=1;i<=n;i++){
            scanf("%d%d",&q[i].x,&q[i].num);        
        }
        for(i=n;i>=1;i--){
            modify(1,q[i].x+1,q[i].num);
        }
         for(i=1;i<=n;i++)
         printf("%d ",ans[i]);
         cout<<endl;
    }
}
View Code

 

POJ2828 Buy Tickets (线段树)

原文:https://www.cnblogs.com/ctyakwf/p/12331321.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!