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 ...
随机推荐
- linux 使用笔记2
安装chrome浏览器在Fedora 23 下载pub wget https://dl-ssl.google.com/linux/linux_signing_key.pub 安装pub sudo rp ...
- Django 访问admin提示ViewDoesNotExist at /admin/
ViewDoesNotExist at /admin/ Could not import django.views.generic.simple.redirect_to. Parent module ...
- Codeforces 792B. Counting-out Rhyme
B. Counting-out Rhyme time limit per test: 1 second memory limit per test: 256 megabytes input: stan ...
- 看懂 Fiddler 的瀑布图
最近准备给组内的新同学们分享下 Fiddler 这枚神器,可以讲的地方太多,我打算把一节课讲不完的内容写在博客上,大家可以随便看看.今天先介绍下 Fiddler 的瀑布图. 每个网络请求都会经历域名解 ...
- 在linux虚拟机上安装Docker
1.简介Docker是一个开源的应用容器引擎:是一个轻量级容器技术: Docker支持将软件编译成一个镜像:然后在镜像中各种软件做好配置,将镜像发布出去,其他使用者可以直接使用这个镜像: 运行中的这个 ...
- centos7中输入ifconfig出现ens33,没有eth0(转)
vmware安装的centos7中没有出现eth0网卡,也没有ip,不能上网,输入ifconfig后如下图 解决办法 1.编辑网卡的配置文件 vi /etc/sysconfig/network-scr ...
- nginx 域名(虚拟)部署nodejs项目
首先说下我的情况,Windows+mongodb开发的简单nodejs 小博客系统, 配置部署到centos7 nginx下,mongodb还是在我Windows机器下, 1.Linux安装node. ...
- cocos jsb工程转html 工程
1 CCBoot.js prepare方法:注掉下面这行,先加载moduleConfig中的脚本后加载user脚本 //newJsList = newJsList.concat(jsList); // ...
- 图解http学习笔记【一】
不想单纯的把书里的知识点罗列一遍 这周,我们的安全代码终于改完了.我在微信上报了个叫 一修读书的课程,现在已经听了6天.感觉并不是很神奇,聊胜于无.倒是趁着当当搞活动买回来好几本书,其中就有这本图解h ...
- 核心一:DI
1.DI:中文名称:依赖注入 2.英文名称:(Dependency Injection) 3.DI是什么?? 3.1 DI和IoC是一样的 3.2 当一个类(A)中需要依赖另一类(B)对象时,把B赋值 ...