POJ 2828 Buy Tickets(线段树单点更新)
2016-02-26 11:08
357 查看
大意:有n个人在排队,接下来n行每行有两个数 k,m分别代表m要插在第k个人的后边,求最终的序列。
思路:先建立区间树,然后进行区间缩减,如果正者建图的话,有可能被其他的数挤下去,所以可以从后向前建树,这样就是个稳定的序列了,注意在查询的时候向右子区间取得时候应当改变存放位置,为当前区间的x-sum[rt<<1].
思路:先建立区间树,然后进行区间缩减,如果正者建图的话,有可能被其他的数挤下去,所以可以从后向前建树,这样就是个稳定的序列了,注意在查询的时候向右子区间取得时候应当改变存放位置,为当前区间的x-sum[rt<<1].
#include<map> #include<queue> #include<cmath> #include<iostream> #include<cstdio> #include<stack> #include<cstring> #include<algorithm> #define LL int #define inf 0x3f3f3f3f const double PI=acos(-1.0); using namespace std; #define ls l,mid,rt<<1 #define rs mid+1,r,rt<<1|1 int sum[200010*6],num[200010]; struct node{ int k,m; }q[200010]; void bu(int l,int r,int rt){ sum[rt]=r-l+1; if(l==r) return ; int mid=(l+r)>>1; bu(ls); bu(rs); } int Query(int x,int l,int r,int rt){ --sum[rt]; if(l==r){ return l; } int mid=(l+r)>>1; if(sum[rt<<1]>=x){ Query(x,ls); } else{ Query(x-sum[rt<<1],rs); } } int main(){ int n,m,i,j,k; while(~scanf("%d",&n)){ for(i=0;i<n;i++){ scanf("%d %d",&q[i].k,&q[i].m); } bu(1,n,1); for(i=n-1;i>=0;i--){ int p=Query(q[i].k+1,1,n,1); num[p]=q[i].m; } for(i=1;i<=n;++i){ printf(i==n?"%d\n":"%d ",num[i]); } } return 0; }
相关文章推荐
- 初学ACM - 组合数学基础题目PKU 1833
- 线段树题集
- POJ ACM 1001
- POJ ACM 1002
- 1611:The Suspects
- POJ1089 区间合并
- POJ 2635 The Embarrassed Cryptographe
- POJ 3292 Semi-prime H-numbers
- POJ 2773 HAPPY 2006
- POJ 3090 Visible Lattice Points
- POJ-2409-Let it Bead&&NYOJ-280-LK的项链
- POJ-1695-Magazine Delivery-dp
- POJ1523 SPF dfs
- POJ-1001 求高精度幂-大数乘法系列
- POJ-1003 Hangover
- POJ-1004 Financial Management
- 用单调栈解决最大连续矩形面积问题
- 线段树
- 2632 Crashing Robots的解决方法
- 1573 Robot Motion (简单题)