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操 ...
随机推荐
- mac下搭建基于vue-cli 3.0的Element UI 项目
1.安装yarn管理工具(包含node.js); 2.安装全局vue-cli全家桶: yarn global add @vue/cli 3.创建.测试一个vue-cli项目: vue create a ...
- 转载- ACM常见的各种说法
from : http://blog.csdn.net/qq_15015129/article/details/52738184 1.答案错误 —— wrong answer 就是最常见的.这个没办法 ...
- Javascript知识点汇总-初级篇
JavaScript的数据类型都有什么? 基本数据类型:String,Boolean,Number,Undefined, Null 引用数据类型:Object(Array,Date,RegExp,Fu ...
- [Vue]实例化Vue时的两种挂载方式el与$mount
Vue 的$mount()为手动挂载,在项目中可用于延时挂载(例如在挂载之前要进行一些其他操作.判断等),之后要手动挂载上.new Vue时,el和$mount并没有本质上的不同. 1.el Vue实 ...
- HTML 参考手册- (HTML5 标准)
HTML 参考手册- (HTML5 标准) 功能排序 New : HTML5 新标签 标签 描述 基础 <!DOCTYPE> 定义文档类型. <html> 定义一个 HT ...
- 在xampp集成环境下使用 php 连接oracle
今天搞了大半天,终于成功了. 1. 首先需要让xampp支持oracle,直接按这个网页上说的做就行.http://nimal.info/blog/2009/activate-oracle-on-xa ...
- python基础方法
一.忽略大小写相等upper(),lower() def cmp(str1,str2): return str1.upper()==str2.upper() list1 = 'MAC' list2 = ...
- Kotlin------类和对象(二)
get/set方法 声明一个属性的完整语法是 var <propertyName>[: <PropertyType>] [= <property_initializer& ...
- tinyxml解析xml
基于tinyxml做的简单的xml解析. 1.创建xml bool CreateXmlFile(string& szFileName) {//创建xml文件,szFilePath为文件保存的路 ...
- hdu 4679 Terrorist’s destroy 树的直径+dp
题意:给你一棵树,每条边都有值W,然后问你去掉一条边,令val = w*max(两颗新树的直径),求val最小值~ 做法,先求树的直径,然后算出直径上每个点的最长枝条长度.这样对于每一条边,假如是枝条 ...