2018宁夏邀请赛 Continuous Intervals(单调栈 线段树
https://vjudge.net/problem/Gym-102222L
题意:给你n个数的序列,让判断有几个区间满足排完序后相邻两数差都不大于1。
题解:对于一个区间 [L,R],记最大值为 max、最小值为 min、数 字种类数为 cnt,那么这个区间是 continuous interval 当且 仅当 max−min+ 1 = cnt。 考虑从小到大枚举 R,用线段树维护每个 L 的区间 [L,R] 的 max−min−cnt 的值。 由于总有 max−min+1 ≥cnt,那么只需要维护线段树上每 个 L 对应的 max−min−cnt 的最小值,以及有多少个 L 取 到这个最小值。 当 R 变大时,每个 L 对应的三个值都需要进行修改。对于 max 和 min,可以用单调栈来维护后缀 max 和 min,然后在 线段树上进行区间加减操作,对于 cnt,只需要在线段树上 对区间 [lastai + 1,R] 进行加减操作。
#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=2000010;
int Mn[maxn],lazy[maxn],sum[maxn],a[maxn];
int q1[maxn],t1,q2[maxn],t2;
map<int,int>mp;
void build(int Now,int L,int R)
{
sum[Now]=R-L+1; Mn[Now]=lazy[Now]=0;
if(L==R) return ; int Mid=(L+R)>>1;
build(Now<<1,L,Mid);
build(Now<<1|1,Mid+1,R);
}
void pushdown(int Now)
{
if(!lazy[Now]) return ;
Mn[Now<<1]+=lazy[Now]; Mn[Now<<1|1]+=lazy[Now];
lazy[Now<<1]+=lazy[Now]; lazy[Now<<1|1]+=lazy[Now];
lazy[Now]=0;
}
void pushup(int Now)
{
Mn[Now]=min(Mn[Now<<1],Mn[Now<<1|1]);
if(Mn[Now<<1]==Mn[Now<<1|1]) sum[Now]=sum[Now<<1]+sum[Now<<1|1];
else if(Mn[Now<<1]<Mn[Now<<1|1]) sum[Now]=sum[Now<<1];
else sum[Now]=sum[Now<<1|1];
}
void update(int Now,int L,int R,int l,int r,int v)
{
if(l>r) return ;
if(L==R) {
Mn[Now]+=v;
return ;
}
if(l<=L&&r>=R){
Mn[Now]+=v; lazy[Now]+=v;
return ;
}
int Mid=(L+R)>>1; pushdown(Now);
if(l<=Mid) update(Now<<1,L,Mid,l,r,v);
if(r>Mid) update(Now<<1|1,Mid+1,R,l,r,v);
pushup(Now);
}
int main()
{
int T,N,C=0; ll ans;
scanf("%d",&T);
while(T--){
scanf("%d",&N);
rep(i,1,N) scanf("%d",&a[i]);
build(1,1,N);
t1=t2=0; ans=0; mp.clear();
rep(i,1,N){
update(1,1,N,i,i,-1);
while(t1&&a[i]>=a[q1[t1]]){
update(1,1,N,q1[t1-1]+1,q1[t1],a[i]-a[q1[t1]]);
t1--;
}
q1[++t1]=i; //单减栈 while(t2&&a[i]<=a[q2[t2]]){
update(1,1,N,q2[t2-1]+1,q2[t2],a[q2[t2]]-a[i]);
t2--;
}
q2[++t2]=i; //单增栈 update(1,1,N,mp[a[i]]+1,i-1,-1); mp[a[i]]=i;
ans+=sum[1];
}
printf("Case #%d: %lld\n",++C,ans);
}
return 0;
}
2018宁夏邀请赛 Continuous Intervals(单调栈 线段树的更多相关文章
- 2018ICPC银川 L Continuous Intervals 单调栈 线段树
题意:给你一个序列,问你这个序列有多少个子区间,满足把区间里的数排序之后相邻两个数之间的差 <= 1 ? 思路:https://blog.csdn.net/u013534123/article/ ...
- 2018宁夏邀请赛 L Continuous Intervals(单调栈+线段树)
2018宁夏邀请赛 L Continuous Intervals(单调栈+线段树) 传送门:https://nanti.jisuanke.com/t/41296 题意: 给一个数列A 问在数列A中有多 ...
- 洛谷P4198 楼房重建 单调栈+线段树
正解:单调栈+线段树 解题报告: 传送门! 首先考虑不修改的话就是个单调栈板子题昂,这个就是 然后这题的话,,,我怎么记得之前考试好像有次考到了类似的题目昂,,,?反正我总觉着这方法似曾相识的样子,, ...
- 南昌邀请赛I.Max answer 单调栈+线段树
题目链接:https://nanti.jisuanke.com/t/38228 Alice has a magic array. She suggests that the value of a in ...
- 2019ICPC南昌邀请赛网络赛 I. Max answer (单调栈+线段树/笛卡尔树)
题目链接 题意:求一个序列的最大的(区间最小值*区间和) 线段树做法:用单调栈求出每个数两边比它大的左右边界,然后用线段树求出每段区间的和sum.最小前缀lsum.最小后缀rsum,枚举每个数a[i] ...
- The Preliminary Contest for ICPC China Nanchang National Invitational I. Max answer (单调栈+线段树)
题目链接:https://nanti.jisuanke.com/t/38228 题目大意:一个区间的值等于该区间的和乘以区间的最小值.给出一个含有n个数的序列(序列的值有正有负),找到该序列的区间最大 ...
- 2019南昌网络赛-I(单调栈+线段树)
题目链接:https://nanti.jisuanke.com/t/38228 题意:定义一段区间的值为该区间的和×该区间的最小值,求给定数组的最大的区间值. 思路:比赛时还不会线段树,和队友在这题上 ...
- 网络赛 I题 Max answer 单调栈+线段树
题目链接:https://nanti.jisuanke.com/t/38228 题意:在给出的序列里面找一个区间,使区间最小值乘以区间和得到的值最大,输出这个最大值. 思路:我们枚举每一个数字,假设是 ...
- [CF1083D]The Fair Nut’s getting crazy[单调栈+线段树]
题意 给定一个长度为 \(n\) 的序列 \(\{a_i\}\).你需要从该序列中选出两个非空的子段,这两个子段满足 两个子段非包含关系. 两个子段存在交. 位于两个子段交中的元素在每个子段中只能出现 ...
随机推荐
- 理解SVG中的 viewport,viewBox, preserveAspectRatio
_ 阅读目录 一:理解viewport 二:理解viewBox 三:理解 preserveAspectRatio 回到顶部 一:理解viewport 该属性表示的是SVG可见区域的大小.或者也可以叫画 ...
- Java8中的流操作-基本使用&性能测试
为获得更好的阅读体验,请访问原文:传送门 一.流(Stream)简介 流是 Java8 中 API 的新成员,它允许你以声明式的方式处理数据集合(通过查询语句来表达,而不是临时编写一个实现).这有点儿 ...
- CentOS系统故障 | 一桩"血案"引发的容器存储驱动比较
写在前面: 由于红帽在Linux界的影响力,相信很多朋友在测试和生产系统用的是RedHat或者CentOS系统,这次我在CentOS系统上遇到了一个很有意思的故障,通过这次故障的原因分析及解决,特意写 ...
- Flink 从0到1学习 —— Flink 中如何管理配置?
前言 如果你了解 Apache Flink 的话,那么你应该熟悉该如何像 Flink 发送数据或者如何从 Flink 获取数据.但是在某些情况下,我们需要将配置数据发送到 Flink 集群并从中接收一 ...
- java8-流的操作
流的操作 流的使用一般包括三件事: 一个数据源来执行一个查询; 一个中间操作链,形成一条流的流水线; 一个终端操作,执行流水线,并能生成结果 中间操作 操作 类型 返回类型 操作参数 函数描述符 fi ...
- kali Metasploit 连接 Postgresql 默认密码
使用 metasploit 时, 1. 启动 postgresql service postgresql start 2. 自行测试 postgresql 是否安装成功 根据需要,自行 修改 post ...
- 史上最全面的SignalR系列教程-1、认识SignalR
SignalR 是什么? SignalR 是一个面向 ASP.NET 开发人员的库,可简化将实时 web 功能添加到应用程序的过程. 实时 web 功能是让服务器代码将内容推送到连接的客户端立即可用, ...
- 【Java例题】7.1 线程题1-时间显示线程
1.时间显示线程.设计一个示线程子类,每秒钟显示一次当前时间:然后编写主类,在主函数中定义一个线程对象,并启动这个线程 package chapter7; import java.text.Simpl ...
- JAVA基础知识(二):List接口、ArrayList类和LinkedList类
List接口继承了Collection接口,位于java.util包中.它包含Collection接口的所有方法,外加其他一些方法(具体实现参考源码),比较重要的有: anyType get(int ...
- 前端登录jq图形验证码
<!DOCTYPE html><html lang="zh"><head> <meta charset="UTF-8" ...