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线段树单点更新——逆序更新的更多相关文章

  1. poj2828 线段树单点更新

    Buy Tickets Time Limit: 4000 MS Memory Limit: 65536 KB 64-bit integer IO format: %I64d , %I64u Java ...

  2. POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和)

    POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和) 题意分析 卡卡屋前有一株苹果树,每年秋天,树上长了许多苹果.卡卡很喜欢苹果.树上有N个节点,卡卡给他们编号1到N,根 ...

  3. POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化)

    POJ.2299 Ultra-QuickSort (线段树 单点更新 区间求和 逆序对 离散化) 题意分析 前置技能 线段树求逆序对 离散化 线段树求逆序对已经说过了,具体方法请看这里 离散化 有些数 ...

  4. HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)

    HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...

  5. POJ 1804 Brainman(5种解法,好题,【暴力】,【归并排序】,【线段树单点更新】,【树状数组】,【平衡树】)

    Brainman Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 10575   Accepted: 5489 Descrip ...

  6. HDU 1754 I Hate It 线段树单点更新求最大值

    题目链接 线段树入门题,线段树单点更新求最大值问题. #include <iostream> #include <cstdio> #include <cmath> ...

  7. HDU 1166 敌兵布阵(线段树单点更新)

    敌兵布阵 单点更新和区间更新还是有一些区别的,应该注意! [题目链接]敌兵布阵 [题目类型]线段树单点更新 &题意: 第一行一个整数T,表示有T组数据. 每组数据第一行一个正整数N(N< ...

  8. poj 2892---Tunnel Warfare(线段树单点更新、区间合并)

    题目链接 Description During the War of Resistance Against Japan, tunnel warfare was carried out extensiv ...

  9. HDU 1166 敌兵布阵(线段树单点更新,板子题)

    敌兵布阵 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...

随机推荐

  1. Pandas设置值

    1.创建数据 >>> dates = pd.date_range(', periods=6) >>> df = pd.DataFrame(np.arange(24) ...

  2. pop回到之前的某一个页面

    循环遍历 - (void)backHome:(UIButton *)button { self.navigationController.navigationBarHidden = NO; 4 Cas ...

  3. [Hbase]Hbase章2 Hbase读写过程解析

    写数据 Hbase使用memstore和storefile存储对表的更新.数据在更新时首先写入hlog和memstore,memstore中的数据是排序的,当memstore累计到一定的阀值时,就会创 ...

  4. 局外者看 -- 美团 vs 滴滴

    1. 美团 美团外面 美团打车 美团云服务 2. 滴滴 滴滴打车 滴滴外面 滴滴云服务 这是一场企业级别的战争,而且是本土战争,时间开始于何时,不知道,现在写这个博客的时间是2018年3月21日下午. ...

  5. 【Web】Sublime Text 3 安装+注册+汉化

    Sublime Text 介绍 Sublime Text 是一个代码编辑器,也是HTML和散文先进的文本编辑器.Sublime Text是由程序员Jon Skinner于2008年1月份所开发出来,它 ...

  6. redis2

    一.安装redis 1)     下载redis安装包 可去官网http://redis.io ,也可通过wget命令, wget http://download.redis.io/redis-sta ...

  7. [转]order by 与索引

    ORDER BY 通常会有两种实现方法,一个是利用有序索引自动实现,也就是说利用有序索引的有序性就不再另做排序操作了.另一个是把结果选好之后再排序. 用有序索引这种,当然是最快的,不过有一些限制条件, ...

  8. Linux 下移植QT(1)---tslib 1.4.0移植

    步骤1:下载工具包 如下图 链接在此,点我. 步骤2:将tslib文件放入Linux虚拟机中, 步骤3:解压源码 tar -xvf tslib-1.4.tar cd tslib-1.4 步骤4:执行a ...

  9. Oracle常用命令-用户、表空间、赋权限、导入导出

    1.1   删除表空间 drop tablespace QBKJ including contents and datafiles; 1.2   删除用户 drop user admin cascad ...

  10. C#中string类型是值类型还是引用类型?(转)

    出处:https://www.cnblogs.com/dxxzst/p/8488567.html .Net框架程序设计(修订版)中有这样一段描述:String类型直接继承自Object,这使得它成为一 ...