poj 2828 Buy Tickets
来源:互联网 发布:加qq群软件 编辑:程序博客网 时间:2024/06/10 04:11
题目链接:点击打开链接
题意:插队,输入p,v则将代号为v的人插到p+1的位置上,后面的人依次往后串。
观察发现实际上把从后往前看,就是讲代号为v的人插到当前第v+1个空位上,这个人的位置就不会动了。这样只要查询第v+1个空位在哪就行了。
线段树维护区间中的空位数。
查询时,如果当前区间的左子树空位数大于等于需要的空位数就在左子树中查,如果不够就在右子树中查,但是需要的空位数要改为pos - 左子树空位,因为这些在左子树中用掉了。
查询到叶子时就是想要的位置了,将这个空位数减1(实际上就是变成0),然后pushup回溯。
代码:
#include <iostream>#include <cstdio>#include <cstring>#define MAX 200010#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1using namespace std;int N;int a[MAX*4];struct note{ int pos,val;}in[MAX];int res[MAX];void pushup(int rt){ a[rt]=a[rt<<1]+a[rt<<1|1];}void build(int l,int r,int rt){ a[rt]=r-l+1; if(l==r) return ; int m=(l+r)>>1; build(lson); build(rson);}int query(int p,int l,int r,int rt){ if(l==r){ a[rt]--; return r; } int m=(l+r)>>1; int res=0; if(a[rt<<1]>=p) res=query(p,lson); else { res=query(p-a[rt<<1],rson); } pushup(rt); return res;}int main(){ while(~scanf("%d",&N)){ for(int i=1;i<=N;i++){ scanf("%d%d",&in[i].pos,&in[i].val); } build(1,N,1); for(int i=N;i>=1;i--){ int t=query(in[i].pos+1,1,N,1); /*for(int i=1;i<=7;i++){ cout<<a[i]<<" "; } cout<<endl;*/ res[t]=in[i].val; } for(int i=1;i<N;i++){ printf("%d ",res[i]); } printf("%d\n",res[N]); } return 0;}
0 0
- poj 2828 Buy Tickets
- poj 2828 Buy Tickets
- poj 2828 Buy Tickets
- poj 2828 Buy Tickets
- POJ 2828 Buy Tickets
- Poj 2828 Buy Tickets
- poj 2828 buy tickets
- POJ 2828 Buy Tickets
- poj 2828 Buy Tickets
- poj 2828 Buy Tickets
- POJ 2828 - Buy Tickets
- POJ 2828 - Buy Tickets
- POJ-2828-Buy Tickets
- poj 2828 Buy Tickets
- poj 2828 Buy Tickets
- poj 2828 Buy Tickets
- POJ 2828 Buy Tickets
- POJ 2828 Buy Tickets
- 彻底理解并查集
- Cloud网站书籍板块
- ECSHOP商品评论须购买过该商品且只能评价一次
- Android开发问题汇总
- oracle创建表空间
- poj 2828 Buy Tickets
- android一种统计工具Flurry的使用说明
- https原理
- 算法与数据结构面试题
- Android Animations动画使用详解
- mysql基础
- 上海巨鳄是如何突围商业市场同质化?
- vim配置及插件安装管理(超级详细)
- hdu 4932 Miaomiao's Geometry