poj 2828【线段树 单点更新】
2024-09-06 14:01:07
还是弱啊。思维是个好东西。。。
刚开始想来想去用线段树存人的话不仅超时,而且存不下。。。居然是存空位!
sum[]数组存这个序列空位个数,然后逆序遍历。逆序好理解,毕竟最后一个人插进来位置已经可以确定了,前面的位置就根据他来更新。
#include<iostream>
#include<cstdio>
#define mid int m=(l+r)>>1
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
const int maxn=;
int sum[maxn<<],ans[maxn<<];
int N,p[maxn],v[maxn]; void Build(int l,int r,int rt)//建树存空位
{
sum[rt]=r-l+;//初始建树时线段对应的空位数就是线段长度(点看成长度为1的线段)
if(l==r) return;
mid;
Build(lson);
Build(rson);
} void PushUp(int rt)
{
sum[rt]=sum[rt<<]+sum[rt<<|];
} void Update(int pos,int val,int l,int r,int rt)
{
if(l==r){
ans[l]=val;//递归到节点,用ans[]数组记录第l个人的val值。
sum[rt]--;//空位数减1
return;
}
mid;
if(pos<=sum[rt<<]) Update(pos,val,lson);//如果当前节点左孩子的空位数足够,就递归左孩子
else Update(pos-sum[rt<<],val,rson);//如果左孩子的空位数不够,那么就递归又孩子,但空位数要变成pos-sum[rt<<1]
PushUp(rt);//向上更新父节点的空位数
} int main()
{
while(scanf("%d",&N)==)
{
Build(,N,);
for (int i=;i<=N;i++) scanf("%d%d",&p[i],&v[i]);
for (int i=N;i>=;i--){
Update(p[i]+,v[i],,N,);//逆序遍历
}
for (int i=;i<N;i++) printf("%d ",ans[i]);
printf("%d\n",ans[N]);
}
return ;
}
poj 2828
最新文章
- iOS-Xcode7 网络连接
- 重构第29天 去除中间人对象(Remove Middle Man)
- [C#/.NET]Entity Framework(EF) Code First 多对多关系的实体增,删,改,查操作全程详细示例
- #Cocos2d+lua#android+Eclipse工程编译设置
- C++学习笔记37:元编程
- A Tour of Go Arrays
- 用XAML做网页!!—广告展示区
- 异常:failed for object com.sdu.crm.pojo.Customer@136a986 [java.lang.NullPointerException]
- unity3d自带帮助文档的打开方法
- Ansible性能调优
- java程序调用CMD命令启动tomcat替换环境变量
- IIS网站部署后,程序常见错误记录
- angular 官网英雄案例 报错整理
- Nginx 学习笔记(十)介绍HTTP / 2服务器推送(译)
- ADO.NET连接字符串大全
- db2 reorg table failed处理
- docker图形化管理工具portainer
- SpringBoot Logback日志配置
- log4j(三)——如何控制不同级别的日志信息的输出?
- BZOJ1299 [LLH邀请赛]巧克力棒