POJ2828线段树单点更新——逆序更新
Description
输入n个有序对< pi, vi >,pi表示在第pi个位置后面插入一个值为vi的人,并且pi是不降的。输出最终得到的v的序列
Input
多组用例,每组用例第一行为有序对组数n,之后n行每行两个整数表示一个有序对,以n=0结束输入
Output
对于每组用例,输出最后得到的序列
Sample Input
4
0 77
1 51
1 33
2 69
4
0 20523
1 19243
1 3890
0 31492
Sample Output
77 33 69 51
31492 20523 3890 19243
单点插入线段树——所以建树的时候叶子节点应该为大于n的第一个数(cnt = 2 ^ k > n)
建树的时候我们logn找到该点向下更新叶子和向上更新根节点特别的我们要记录这个节点还有多少空位
为什么要逆序?
因为最后的元素可以确定位置,而忽略前面元素的影响
例如 0 10 0 11
我们逆序来插入值 11 ?
?代表还有空
11插入后,那个节点记录表示空位是0
所以插入0 10的时候会通过判断来往?的位置走~
差不多,自己手想一下就好
void build()
{
int s;
for(s = 1;s < n;s <<= 1);
//之所以要出来大于n画一画就好了,n那一层就算没有占满,也要开一层下面的吧 for(int i = s;i < 2 * s;i++)//叶子
{
tree[i].l = tree[i].r = i - s + 1;
tree[i].cnt = 1;
} for(int i = s-1;i >= 1;i--)//根
{
tree[i].l = tree[2*i].l;
tree[i].r = tree[2*i+1].r;
tree[i].cnt = tree[2*i].cnt + tree[2*i+1].cnt;
}
}
这是第一种建树,也可以常规来
void build(int rt, int left, int right)
{
tree[rt].l = left;
tree[rt].r = right;
tree[rt].cnt = right - left + 1;
if(left == right)
return;
int mid = (left + right) >> 1;
build(rt<<1,left,mid);
build(rt<<1|1,mid + 1,right);
}
code......
//****单点更新线段树
#include <cstdio>
#include <algorithm>
#include <string.h>
#define inf (1 << 29)
using namespace std;
const int maxn = 2e5 + 100;
struct node
{
int pos;
int num;
}p[maxn];
struct node2{
int l,r,cnt;
}tree[maxn << 2];
int n,ans[maxn];
void build(int rt, int left, int right)
{
tree[rt].l = left;
tree[rt].r = right;
tree[rt].cnt = right - left + 1;
if(left == right)
return;
int mid = (left + right) >> 1;
build(rt<<1,left,mid);
build(rt<<1|1,mid + 1,right);
}
/*void build()
{
int s;
for(s = 1;s < n;s <<= 1);
//之所以要出来大于n画一画就好了,n那一层就算没有占满,也要开一层下面的吧 for(int i = s;i < 2 * s;i++)//叶子
{
tree[i].l = tree[i].r = i - s + 1;
tree[i].cnt = 1;
} for(int i = s-1;i >= 1;i--)//根
{
tree[i].l = tree[2*i].l;
tree[i].r = tree[2*i+1].r;
tree[i].cnt = tree[2*i].cnt + tree[2*i+1].cnt;
}
}*/
void insertpoint(int i,int pos,int num)
{
if(tree[i].l == tree[i].r)
{
ans[tree[i].l] = num;
tree[i].cnt = 0;
return;
} if(pos <= tree[2*i].cnt)
insertpoint(2*i,pos,num);
else
insertpoint(2*i+1,pos - tree[2*i].cnt,num);
tree[i].cnt--;
}
int main()
{
while(~scanf("%d",&n))
{
int k = 0;
for(k = 1;k < n;k <<= 1);
build(1,1,k);
for(int i = 0;i < n;++i)
scanf("%d%d",&p[i].pos,&p[i].num);
for(int i = n - 1;i >= 0;i--)
insertpoint(1,p[i].pos + 1,p[i].num);
for(int i = 1;i <= n;i++)
{
printf("%d%c",ans[i],i == n ? '\n' : ' ');
}
} return 0; }
POJ2828线段树单点更新——逆序更新的更多相关文章
- poj2828 线段树单点更新
Buy Tickets Time Limit: 4000 MS Memory Limit: 65536 KB 64-bit integer IO format: %I64d , %I64u Java ...
- POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和)
POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和) 题意分析 卡卡屋前有一株苹果树,每年秋天,树上长了许多苹果.卡卡很喜欢苹果.树上有N个节点,卡卡给他们编号1到N,根 ...
- POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化)
POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化) 题意分析 前置技能 线段树求逆序对 离散化 线段树求逆序对已经说过了,具体方法请看这里 离散化 有些数 ...
- HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)
HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...
- POJ 1804 Brainman(5种解法,好题,【暴力】,【归并排序】,【线段树单点更新】,【树状数组】,【平衡树】)
Brainman Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 10575 Accepted: 5489 Descrip ...
- HDU 1754 I Hate It 线段树单点更新求最大值
题目链接 线段树入门题,线段树单点更新求最大值问题. #include <iostream> #include <cstdio> #include <cmath> ...
- HDU 1166 敌兵布阵(线段树单点更新)
敌兵布阵 单点更新和区间更新还是有一些区别的,应该注意! [题目链接]敌兵布阵 [题目类型]线段树单点更新 &题意: 第一行一个整数T,表示有T组数据. 每组数据第一行一个正整数N(N< ...
- poj 2892---Tunnel Warfare(线段树单点更新、区间合并)
题目链接 Description During the War of Resistance Against Japan, tunnel warfare was carried out extensiv ...
- HDU 1166 敌兵布阵(线段树单点更新,板子题)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
随机推荐
- JavaScript中双叹号(!!)和单叹号(!)
转自:JavaScript中双叹号(!!)作用 经常看到这样的例子: var a: var b=!!a; a默认是undefined.!a是true,!!a则是false,所以b的值是false,而不 ...
- Gulp应用场景
转自:Gulp教程之:Gulp能做什么,前端装逼为何要用它 我们先说说 平时web开发遇到的一些场景 和 苦恼无奈的情况: JavaScript和CSS的版本问题 我们都知道 JavaScript ...
- C++树的插入和遍历(关于指针的指针,指针的引用的思考)
题目 写一个树的插入和遍历的算法,插入时按照单词的字典顺序排序(左边放比它"小"的单词,右边放比它"大"的单词),对重复插入的单词进行计数. 程序源码 #inc ...
- Quartus11中新建工程
最近在使用CycloneII的开发板,但是高版本的Quartus不支持II系列的开发,于是只能用Q11了.好久没玩FPGA了,新建工程的过程中遇到了一些问题,这里把这些问题记下了以便以后查看. Qua ...
- PAT 1049 数列的片段和(20)(代码+思路分析)
1049 数列的片段和(20)(20 分) 给定一个正数数列,我们可以从中截取任意的连续的几个数,称为片段.例如,给定数列{0.1, 0.2, 0.3, 0.4},我们有(0.1) (0.1, 0.2 ...
- 如何修改隐藏Zblog/WordPress默认后台登录地址
我相信很多博主站长都遇到过站点被暴力破解,虽然未被破解,但是经常收到那些尝试登录失败的邮件提醒也会心慌慌的.对于这种情况,最好的办法就是修改/隐藏我们的后台登录地址. 关于zblogASP后台登录地址 ...
- Linux入门练习操作命令
查看目录命令 1. 显示目录下所有文件 2.显示所有文件,包括隐藏文件 创建目录命令 1.在改目录下创建文件夹“practise” 切换目录 1.切换到指定的目录 2.切换到上一级目录 3.还在当前目 ...
- oracle导入sql文件关闭回馈
set feedback off --关闭回馈 set define off --关闭转义关键字
- 【Web】前端裁剪图片,并上传到服务器(Jcrop+canvas)
web网站中常常有的功能:上传头像.上传封面等:一般图片都有一定的比例限制,所以需要前端在上传图片时,进行裁剪,并把裁剪后的图片进行上传. 本例采用Jcrop插件实现裁剪效果,canvas裁剪图片,并 ...
- AJAX-DOM事件
1.DOM事件 1.select的onchange事件 当选项框中的内容发生改变时需要出发的事件.2.Ajax 1.名词解释 1.同步 在一个任务进行中,不能开启其它的任务. 同步访问:浏览器在向服务 ...