POJ 2828 线段树
来源:互联网 发布:网络经济学ppt 编辑:程序博客网 时间:2024/06/14 14:10
题目链接:http://poj.org/problem?id=2828
题意:队列问题,每个人会插入一个位置,每个人有固定id,即val。输出最后队列。
思路:这道题如果正着想会比较难,但是如果考虑从数据末往会考虑就可以发现这个时候序列就已经是固定了的。现在难得就是怎么构建线段树了。考虑每个叶子节点存储一个标志位标志这个位置有没有人,往上的节点存储它的两个儿子中可以放人的个数。查询的时候,如果当前节点p大于左子树可以存储的数量,即p < sum[rt<<1],则访问左子树,意思是把它放在它想放的最靠近的位置,否则访问它的右子树,这时候要考虑迭代的p应该要改变成p-sum[rt<<1]。输出的话,再建立一棵树存储val的值输出就可以了。
#include <iostream>#include <stdio.h>#include <math.h>#include <algorithm>#include <cstring>#include <string>using namespace std;const int maxn = 200005;int a[maxn],val[maxn];int sum[maxn << 2],ans[maxn<<2];void PushUp(int rt){ sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];}void build(int l, int r, int rt){ if (l == r) { sum[rt]=1; return; } int m = (l + r) >> 1; build(l, m, rt << 1); build(m + 1, r, rt << 1 | 1); PushUp(rt);}void update(int p,int val , int l, int r, int rt){ if (l == r) { ans[rt]=val; sum[rt]=0; return; } int m = (l + r) >> 1; if (p<=sum[rt<<1]) update(p,val, l, m, rt << 1); else update(p-sum[rt<<1],val, m + 1, r, rt << 1 | 1);//注意p的变更 PushUp(rt);}void pr(int l,int r,int rt){ if(l==r){ printf("%d ",ans[rt]);return; } int m=(l+r)>>1; pr(l,m,rt<<1); pr(m+1,r,rt<<1|1);}int main(){ int n; while(~scanf("%d",&n)){ for(int i=0;i<n;i++){ scanf("%d%d",&a[i],&val[i]); } build(1,n,1); for(int i=n-1;i>=0;i--){ update(a[i]+1,val[i],1,n,1); } pr(1,n,1); printf("\n"); } return 0;}
阅读全文
0 0
- POJ 2828 (线段树)
- POJ 2828 线段树
- poj 2828 线段树
- poj 2828 (线段树)
- poj 2828 线段树
- poj 2828 线段树
- POJ 2828 线段树
- poj 2828 线段树
- poj 2828 线段树
- poj 2828 线段树
- POJ 2828 线段树
- POJ 2828 线段树
- POJ 2828 线段树 水题
- poj~2828(线段树)
- poj 2828(线段树)
- POJ--2828(线段树)
- POJ 2828 Buy Tickets(线段树)
- POJ 2828 Buy Tickets 线段树
- Qt 学习之路 2(50):自定义可编辑模型
- Android SDK下载速度慢无法更新?使用国内镜像站加速!
- Service中stopSelf(int startId)说明
- 【NOIP】借教室(线段树)
- 将二叉树拆成链表
- POJ 2828 线段树
- ubuntu的recovery mode下修改文件(写操作)
- live555客户端实现流程步骤
- Qt 学习之路 2(51):布尔表达式树模型
- C++中有符号整数的取值范围
- MyBatis逆向工程
- Hibernate 查询方法get与load的不同
- C++基础-构造函数/析构函数/拷贝构造
- Qt 学习之路 2(52):使用拖放