poj2828(Buy Tickets)(线段树单点更新)

来源:互联网 发布:如何设置家庭网络共享 编辑:程序博客网 时间:2024/05/16 07:40

此题的关键在于逆序更新,并且要将pos位置转化为后面的点还未插入时应当剩余的空位置

//最后一个插入到该位置的人的位置是固定的,从后面进行插入操作,pos代表要插入到pos位置//则在前面插入pos时pos前面要留出pos个空位置,去掉后来插入的点#include<cstdio>#include<iostream>using namespace std;const int maxn=200002;int tree[maxn<<2],ans[maxn<<2];struct node{int pos,val;}s[maxn];void Pushup(int p){    tree[p]=tree[p<<1]+tree[p<<1|1]; //维护区间空位置的个数}void Build(int p,int l,int r){    if(l==r)    {        tree[p]=1;        return;    }    int mid=(l+r)/2;    Build(p<<1,l,mid);    Build(p<<1|1,mid+1,r);    Pushup(p);}void Update(int p,int l,int r,int pos,int val) //单点更新{    if(l==r)    {        tree[p]=0;        ans[l]=val;        return;    }    int mid=(l+r)/2;    if(tree[p<<1]>=pos) Update(p<<1,l,mid,pos,val);    else{        Update(p<<1|1,mid+1,r,pos-tree[p<<1],val);    }    Pushup(p); //漏写致错}int main(){    int n;    while(scanf("%d",&n)!=EOF)    {        for(int i=0;i<n;i++)        {            scanf("%d%d",&s[i].pos,&s[i].val);        }        Build(1,1,n);        for(int i=n-1;i>=0;i--)        {            Update(1,1,n,s[i].pos+1,s[i].val);        }        for(int i=1;i<=n;i++)            cout<<ans[i]<<' ';        cout<<endl;    }    return 0;}

0 0