UVALive - 4108 SKYLINE (吉司机线段树)
题意:在一条直线上依次建造n座建筑物,每座建筑物建造完成后询问它在多长的部分是最高的。
比较好想的方法是用线段树分别维护每个区间的最小值mi和最大值mx,当建造一座高度为x的建筑物时,若mi>x则答案无贡献,直接退出,若mx<=x则区间赋值为x,答案加上区间长度。其他情况需要继续递归搜索。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+,inf=0x3f3f3f3f;
int n,mx[N<<],mi[N<<],lz[N<<];
ll ans;
#define ls (u<<1)
#define rs (u<<1|1)
#define mid ((l+r)>>1)
void pu(int u) {mx[u]=max(mx[ls],mx[rs]),mi[u]=min(mi[ls],mi[rs]);}
void change(int u,int x) {mx[u]=mi[u]=lz[u]=x;}
void pd(int u) {if(~lz[u])change(ls,lz[u]),change(rs,lz[u]),lz[u]=-;}
void build(int u=,int l=,int r=) {
lz[u]=-;
if(l==r) {mx[u]=mi[u]=; return;}
build(ls,l,mid),build(rs,mid+,r),pu(u);
}
void upd(int L,int R,int x,int u=,int l=,int r=) {
if(l>R||r<L||x<mi[u])return;
if(l>=L&&r<=R&&x>=mx[u]) {ans+=r-l+,change(u,x); return;}
pd(u),upd(L,R,x,ls,l,mid),upd(L,R,x,rs,mid+,r),pu(u);
}
int main() {
int T;
for(scanf("%d",&T); T--;) {
build(),ans=;
scanf("%d",&n);
while(n--) {
int l,r,x;
scanf("%d%d%d",&l,&r,&x),r--;
upd(l,r,x);
}
printf("%lld\n",ans);
scanf("");
}
return ;
}
这种方法对于随机数据是比较快的,但会被一些极端的数据卡成n^2,比如先来个[1,2,100000],[3,4,100000],...(每两个位置建一座很高的建筑物),然后来一堆[1,100000,1],[1,100000,2],...,遇到这种情况就GG了。
解决方法是改成吉司机线段树(Segment tree beats),稳定nlogn~
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+,inf=0x3f3f3f3f;
int n,mi[N<<],se[N<<],nmi[N<<],lz[N<<];
ll ans;
#define ls (u<<1)
#define rs (u<<1|1)
#define mid ((l+r)>>1)
void pu(int u) {
mi[u]=min(mi[ls],mi[rs]),se[u]=max(mi[ls],mi[rs]);
se[u]=se[u]==mi[u]?min(se[ls],se[rs]):min(se[u],min(se[ls],se[rs]));
nmi[u]=(mi[ls]==mi[u]?nmi[ls]:)+(mi[rs]==mi[u]?nmi[rs]:);
}
void change(int u,int x) {mi[u]=lz[u]=x;}
void pd(int u) {
if(~lz[u]) {
if(mi[ls]<lz[u])change(ls,lz[u]);
if(mi[rs]<lz[u])change(rs,lz[u]);
lz[u]=-;
}
}
void build(int u=,int l=,int r=) {
lz[u]=-;
if(l==r) {mi[u]=,se[u]=inf,nmi[u]=; return;}
build(ls,l,mid),build(rs,mid+,r),pu(u);
}
void upd(int L,int R,int x,int u=,int l=,int r=) {
if(l>R||r<L||mi[u]>x)return;
if(l>=L&&r<=R&&se[u]>x) {change(u,x),ans+=nmi[u]; return;}
pd(u),upd(L,R,x,ls,l,mid),upd(L,R,x,rs,mid+,r),pu(u);
}
int main() {
int T;
for(scanf("%d",&T); T--;) {
build(),ans=;
scanf("%d",&n);
while(n--) {
int l,r,x;
scanf("%d%d%d",&l,&r,&x),r--;
upd(l,r,x);
}
scanf("");
printf("%lld\n",ans);
}
return ;
}
UVALive - 4108 SKYLINE (吉司机线段树)的更多相关文章
- HDU - 5306 Gorgeous Sequence (吉司机线段树)
题目链接 吉司机线段树裸题... #include<bits/stdc++.h> using namespace std; typedef long long ll; ,inf=0x3f3 ...
- BZOJ4355: Play with sequence(吉司机线段树)
题意 题目链接 Sol 传说中的吉司机线段树??感觉和BZOJ冒险那题差不多,就是强行剪枝... 这题最坑的地方在于对于操作1,$C >= 0$, 操作2中需要对0取max,$a[i] > ...
- bzoj4355 Play with sequence(吉司机线段树)题解
题意: 已知\(n\)个数字,进行以下操作: \(1.\)区间\([L,R]\) 赋值为\(x\) \(2.\)区间\([L,R]\) 赋值为\(max(a[i] + x, 0)\) \(3.\)区间 ...
- bzoj5312 冒险(吉司机线段树)题解
题意: 已知\(n\)个数字,进行以下操作: \(1.\)区间\([L,R]\) 按位与\(x\) \(2.\)区间\([L,R]\) 按位或\(x\) \(3.\)区间\([L,R]\) 询问最大值 ...
- bzoj4695 最假女选手(势能线段树/吉司机线段树)题解
题意: 已知\(n\)个数字,进行以下操作: \(1.\)给一个区间\([L,R]\) 加上一个数\(x\) \(2.\)把一个区间\([L,R]\) 里小于\(x\) 的数变成\(x\) \(3.\ ...
- HDU - 6315 吉司机线段树
题意:给出a,b数组,区间上两种操作,给\(a[L,R]\)+1s,或者求\(\sum_{i=l}^{r}a_i/b_i\) 一看就知道是吉司机乱搞型线段树(低配版),暴力剪枝就好 维护区间a的最大值 ...
- HDU 5306 吉司机线段树
思路: 后面nlogn的部分是伪证... 大家可以构造数据证明是这是nlog^2n的啊~ 吉老司机翻车了 //By SiriusRen #include <cstdio> #include ...
- hdu6521 吉司机线段树
http://acm.hdu.edu.cn/showproblem.php?pid=6521 待填 代码 #include<bits/stdc++.h> #define ls o<& ...
- Petrozavodsk Winter-2018. AtCoder Contest. Problem I. ADD, DIV, MAX 吉司机线段树
题意:给你一个序列,需要支持以下操作:1:区间内的所有数加上某个值.2:区间内的所有数除以某个数(向下取整).3:询问某个区间内的最大值. 思路(从未见过的套路):维护区间最大值和区间最小值,执行2操 ...
随机推荐
- python学习笔记glob模块
python有许多的类库,现将学习记录下来,以供以后回顾复习: 1.glob模块 用于文件名操作,匹配指定目录下的文件,返回的是目录加文件名,常用的有两个函数: glob(pattern),返回匹配的 ...
- java的时间获取
System类代表系统,系统级的很多属性和控制方法都放置在该类的内部.该类位于java.lang包. currentTimeMillis方法 public static long currentTim ...
- hdu 1241 搬寝室 水dp
搬寝室 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Problem Desc ...
- nRF5 SDK软件架构及softdevice工作原理
本文将介绍Nordic nRF5 SDK软件架构以及softdevice工作原理,以加深大家对Nordic产品开发的理解,这样开发过程中碰到问题时,大家也知道如何去调试. 如果你刚开始接触nRF5 S ...
- 利用javascript实现页面截图
html2canvas可以通过纯JS对浏览器端经行截屏,但截图的精确度还有待提高,部分css不可识别,所以在canvas中不能完美呈现原画面样式 兼容性: Firefox 3.5+ Google Ch ...
- 【转】python操作mysql数据库
python操作mysql数据库 Python 标准数据库接口为 Python DB-API,Python DB-API为开发人员提供了数据库应用编程接口. Python 数据库接口支持非常多的数据库 ...
- (转)浅谈SQL Server 对于内存的管理
简介 理解SQL Server对于内存的管理是对于SQL Server问题处理和性能调优的基本,本篇文章讲述SQL Server对于内存管理的内存原理. 二级存储(secondary storage) ...
- 多网卡绑定(bond)
通过以下命令查看bond0的工作状态查询能详细的掌握bonding的工作状态,如这个绑定各网卡的工作状态.主备关系.链路侦测时间[root@ASMTS ~]# cat /proc/net/bondin ...
- 第三章 如何使用Burp Suite代理
Burp Proxy 是Burp Suite以用户驱动测试流程功能的核心,通过代理模式,可以让我们拦截.查看.修改所有在客户端和服务端之间传输的数据. 本章主要讲述以下内容: Burp Proxy基本 ...
- ana3+opencv+TensorFlow+NVIDIAGPU 安装
http://blog.csdn.net/qq_30611601/article/details/79067982 这个博客写的挺完整的 当你发现你的anna下载的贼鸡儿的慢,你就需要使用清华的镜像网 ...