poj 2828 线段树

传送门

思路:假设有n个空位,倒着看,往里放人,插的位置的值可以看作前方空位的和,倒着处理一遍即可。

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
struct node
{
    int l,r;
    int c;
}t[800000];
int n,a[200005],b[200005];
int ans[200005];
void build(int ll,int rr,int rot)
{
    t[rot].l=ll;
    t[rot].r=rr;
    if(ll==rr)t[rot].c=1;
    else
    {
        int mid=(ll+rr)/2;
        build(ll,mid,rot<<1);
        build(mid+1,rr,rot<<1|1);
        t[rot].c=t[rot<<1].c+t[rot<<1|1].c;
    }
}
void update(int aa,int rot,int num)
{
    if(t[rot].l==t[rot].r)
    {
        ans[t[rot].l]=b[num];
        t[rot].c=0;
    }
    else
    {
        if(t[rot<<1].c>=aa)update(aa,rot<<1,num);
        else update(aa-t[rot<<1].c,rot<<1|1,num);
        t[rot].c=t[rot<<1].c+t[rot<<1|1].c;
    }
}
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=1;i<=n;i++)scanf("%d%d",&a[i],&b[i]);
        build(1,n,1);
        for(int i=n;i>=1;i--)
        {
            update(a[i]+1,1,i);
        }
        cout<<ans[1];
        for(int i=2;i<=n;i++)cout<<" "<<ans[i];
        cout<<endl;
    }
    return 0;
}


你可能感兴趣的:(线段树,poj,Baoge)