poj 2828 Buy Tickets(线段树)

来源:互联网 发布:德客会员管理系统源码 编辑:程序博客网 时间:2024/06/06 22:14

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

线段树单点更新问题。

从后往前插入,因为最后一个插入某位置的数是确定的。

之后每个节点用sum记录该区间的空位置数,

如果左区间空位置数比要插入位置大,更新左区间,否则更新右区间,并且pos要减去左区间空位置数。

(感觉想到这一点就会比较容易,否则有一种无从下手的感觉。。。)

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int INF=0x3f3f3f3f;const int maxn=200010;int T,n;int sum[maxn],sequence[maxn];struct Point{int pos;int val;}p[maxn];struct segTree{int l;int r;int sum;}node[3*maxn];void PushUp(int id){node[id].sum=node[id<<1].sum+node[id<<1|1].sum;}void build(int id,int l,int r){node[id].l=l;node[id].r=r;node[id].sum=r-l+1;//表示该区间空位置数if(l==r) return ;int mid=(l+r)>>1;build(id<<1,l,mid);build(id<<1|1,mid+1,r);}void Update(int pos,int val,int l,int r,int id){if(l==r){sequence[l]=val;node[id].sum=0;return ;}int mid=(l+r)>>1;if(pos<=node[id<<1].sum)Update(pos,val,l,mid,id<<1);elseUpdate(pos-node[id<<1].sum,val,mid+1,r,id<<1|1);PushUp(id);}int main(){#ifndef ONLINE_JUDGE    freopen("test.in","r",stdin);    freopen("test.out","w",stdout);#endif    while(~scanf("%d",&n)){    build(1,1,n);    for(int i=1;i<=n;i++)    scanf("%d%d",&p[i].pos,&p[i].val);    memset(sum,0,sizeof(sum));    for(int i=n;i>=1;i--)    Update(p[i].pos+1,p[i].val,1,n,1);    for(int i=1;i<=n;i++)    printf("%d%c",sequence[i],i==n?'\n':' ');    }    return 0;}


0 0
原创粉丝点击