poj 2828 Buy Tickets 线段树
来源:互联网 发布:unity3d 渐变透明 编辑:程序博客网 时间:2024/05/16 14:51
这题也是用线段树来解,惭愧的说没在网上找过资料前真没想到这是用线段树做的
刚开始以为是直接把值往里添然后统计之前已经添过的人的数量,当然这个显然是错误的。
后来也是在看了别人的文章之后有了想法。
1、最后来插队的那个人直接能确定他的最终位置
2、从最后的人开始枚举,反过来去考虑整个插队的过程,如果一个人要插在第i个人的后面,那么也就说在他之前应当i个人,而当前已经插入到树中的人其实是在他之后才来的,所以,反过来一想,此时,必须在这个人前面留下i个位置,这i个位置是留给比他先来的人插的
按照这样的过程就能得到最后的队列了
代码中
node中的count表示在该节点下共有多少个空位置没被插队
update就是插队的过程(从最后那个人开始)
如果一个节点的左节点的count>i (i是他要插入的位置,如0的时候必须是留一个空位,这个空位就是把他自己插入的,1的时候留两个,以此类推),往左节点递归,知道最后l==r,否则,就得往右节点插入,而往右节点插入的时候必须算上左节点的空位数,所以得 i-左节点的空位数
(在代码里p就表示这里的i)
输出结果的话其实就是找到线段树的所有叶子,从左往右输出即可
#include <cstdio>#include <cstring>#define FF(i,n) for(int i=0; i<n; i++)const int MAX = 200010;struct node{ int count,val;}tree[MAX<<2];void push_up(int rt){ tree[rt].count = tree[rt<<1].count + tree[(rt<<1)+1].count;}void build(int l,int r,int rt){ if(l==r) { tree[rt].count = 1; tree[rt].val = -1; return; } int mid = (r+l)>>1; build(l,mid,rt<<1); build(mid+1,r,(rt<<1)+1); push_up(rt);}void update(int p,int val,int l,int r,int rt){ if(l==r) { tree[rt].count = 0; tree[rt].val = val; return; } int mid = (r+l)>>1; if(tree[rt<<1].count>p) update(p,val,l,mid,rt<<1); else update(p-tree[rt<<1].count,val,mid+1,r,(rt<<1)+1); push_up(rt);}int cnt;void print(int l,int r,int rt){ if(l==r) { if(cnt) printf(" "); printf("%d",tree[rt].val); cnt++; return; } int mid = (r+l)>>1; print(l,mid,rt<<1); print(mid+1,r,(rt<<1)+1);}int x[MAX],y[MAX];int main(){ int n; while(scanf("%d",&n)==1) { build(1,n,1); FF(i,n) scanf("%d%d",&x[i],&y[i]); FF(i,n) update(x[n-1-i],y[n-1-i],1,n,1); cnt=0; print(1,n,1); puts(""); } return 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【线段树】
- 打印5阶幻方
- sar访谈
- java代码执行js
- px像素、em相对单位,到底是什么意思?
- VC ClistBox 行高
- poj 2828 Buy Tickets 线段树
- 解决FlexPaper分页分段加载问题
- 整理tomcat安全证书 https访问
- VIM 参考手册 For Vim version 7.3
- SCI期刊查询
- Command 模式C++ 代码
- 【集合】ArrayList数组列表类
- java静态方法注意的问题
- 【Win32多线程】异步I/O技术(Overlapped I/O),避免使用多线程