题目链接

题意:在一条直线上依次建造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 (吉司机线段树)的更多相关文章

  1. HDU - 5306 Gorgeous Sequence (吉司机线段树)

    题目链接 吉司机线段树裸题... #include<bits/stdc++.h> using namespace std; typedef long long ll; ,inf=0x3f3 ...

  2. BZOJ4355: Play with sequence(吉司机线段树)

    题意 题目链接 Sol 传说中的吉司机线段树??感觉和BZOJ冒险那题差不多,就是强行剪枝... 这题最坑的地方在于对于操作1,$C >= 0$, 操作2中需要对0取max,$a[i] > ...

  3. bzoj4355 Play with sequence(吉司机线段树)题解

    题意: 已知\(n\)个数字,进行以下操作: \(1.\)区间\([L,R]\) 赋值为\(x\) \(2.\)区间\([L,R]\) 赋值为\(max(a[i] + x, 0)\) \(3.\)区间 ...

  4. bzoj5312 冒险(吉司机线段树)题解

    题意: 已知\(n\)个数字,进行以下操作: \(1.\)区间\([L,R]\) 按位与\(x\) \(2.\)区间\([L,R]\) 按位或\(x\) \(3.\)区间\([L,R]\) 询问最大值 ...

  5. bzoj4695 最假女选手(势能线段树/吉司机线段树)题解

    题意: 已知\(n\)个数字,进行以下操作: \(1.\)给一个区间\([L,R]\) 加上一个数\(x\) \(2.\)把一个区间\([L,R]\) 里小于\(x\) 的数变成\(x\) \(3.\ ...

  6. HDU - 6315 吉司机线段树

    题意:给出a,b数组,区间上两种操作,给\(a[L,R]\)+1s,或者求\(\sum_{i=l}^{r}a_i/b_i\) 一看就知道是吉司机乱搞型线段树(低配版),暴力剪枝就好 维护区间a的最大值 ...

  7. HDU 5306 吉司机线段树

    思路: 后面nlogn的部分是伪证... 大家可以构造数据证明是这是nlog^2n的啊~ 吉老司机翻车了 //By SiriusRen #include <cstdio> #include ...

  8. hdu6521 吉司机线段树

    http://acm.hdu.edu.cn/showproblem.php?pid=6521 待填 代码 #include<bits/stdc++.h> #define ls o<& ...

  9. Petrozavodsk Winter-2018. AtCoder Contest. Problem I. ADD, DIV, MAX 吉司机线段树

    题意:给你一个序列,需要支持以下操作:1:区间内的所有数加上某个值.2:区间内的所有数除以某个数(向下取整).3:询问某个区间内的最大值. 思路(从未见过的套路):维护区间最大值和区间最小值,执行2操 ...

随机推荐

  1. [异常记录(二)] 验证视图状态 MAC 失败。如果此应用程序由网络场或群集承载,请确保 <machineKey> 配置指定了相同的 validationKey 和验证算法。不能在群集中使用 AutoGenerate。

    错误提示: 验证视图状态 MAC 失败.如果此应用程序由网络场或群集承载,请确保 <machineKey> 配置指定了相同的 validationKey 和验证算法.不能在群集中使用 Au ...

  2. C# 生成图片缩略图

    最近项目有部分需求,是关于图片操作部分的, 大致的功能就是图片的保存和展示.但是直接操作原图,程序运行效率太慢.而且如果传输数据量过大的话,可能直接导致调用WCF服务失败的问题. 为了解决这个问题,决 ...

  3. UTF-8文件的Unicode签名BOM(Byte Order Mark)问题记录(EF BB BF)

    背景 楼主测试的批量发送信息功能上线之后,后台发现存在少量的ERROR日志,日志内容为手机号码格式不正确. 此前测试过程中没有出现过此类问题,从运营人员拿到的发送列表的TXT,号码是符合规则的,且格式 ...

  4. int数组的下标为n

    int 类型的数组 先定义int n = 5: 定义int a[n] = {0}; 编译怎么不通过啊?n必须为常量如果想实现你说的,应该用宏#define n 5int a[n]={0};这样就可以了 ...

  5. 仅需15分钟,使用OpenCV+Keras轻松破解验证码

    https://baijia.baidu.com/s?id=1586732712477979223&wfr=pc&fr=app_lst

  6. Android6.0------权限申请RxPermissions

    前面写了Android6.0权限介绍和权限单个,多个申请,用的是纯Java代码,本文主要说的是借助第三方库来实现权限申请. 借助第三方库 RxPermissions来申请6.0权限. RxPermis ...

  7. 1030: [JSOI2007]文本生成器 ac自动机+dp

    https://www.lydsy.com/JudgeOnline/problem.php?id=1030 求长度为m不包含n个子串的种数, 跑完ac自动机之后没办法跑矩阵快速幂,因为状态数比较大(6 ...

  8. 河南省多校联盟二-F 线段树+矩阵

    ---恢复内容开始--- 1284: SP教数学 时间限制: 2 秒  内存限制: 128 MB提交: 24  解决: 4 题目描述 输入 输出 对于每组数据的2操作,输出一行对1e9 + 7取模的答 ...

  9. UVA-1312 Cricket Field (技巧枚举)

    题目大意:在一个w*h的网格中,有n个点,找出一个最大的正方形,使得正方形内部没有点. 题目分析:寻找正方形实质上等同于寻找矩形(只需令长宽同取较短的边长).那么枚举出所有可能的长宽组合取最优答案即可 ...

  10. umilit 修改 linux 最多可打开文件数

    ulimit -n 修改 临时修改:   ulimit -SHn 65535 永久修改:    echo '*  -  nofile  65535' >> /etc/security/li ...