2018icpc宁夏邀请赛_L_Continuous Intervals
题意
给定一个序列,定义连续区间为区间的数排序后,任意两个相邻的数之差不超过1。
分析
- 假设区间最大值为\(max\),最小值为\(min\),不同数个数为\(cnt\),那么问题转化为求满足\(max-min-cnt==1\)的区间个数。
- 统计满足条件的区间个数可以考虑用线段树,主要有三个步骤:
- 枚举右端点\(R\)
- 线段树维护当前所有左端点,即每个叶子节点\((i,i)\),表示序列区间\([i,R]\)
- 统计答案,以\(R\)为右端点的所有区间,即线段树根节点\((1,n)\)
- 更新区间分为两部分
- 第一部分是\(cnt\),也相当于也就是要更新当前\(R\),前面有多少个区间\([i,R]\)以\(a[R]\)作为一个新的不同的数字,显然就是\(a[R]\)上一次出现的位置+1,因为公式中是\(-cnt\),所以更新值为-1。
- 第二部分是\(max\)和\(min\),利用单调栈来维护,当从栈中弹出时,可以得到该元素作为最大/最小值延伸的区间,更新值就是该元素和新的最大/最小值\(a[R]\)之间的差值。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+50;
const int INF=0x3f3f3f3f;
int T,n,a[N];
//线段树(1-n)维护的是当前R作为右端点,([1,R],[2,R]...[R,R])这些区间的情况,也就是一个点代表一个区间
struct ST{
#define ls i<<1
#define rs i<<1|1
#define mid (l+r)/2
//维护区间(mx-mn-cnt)的最小值和最小值的个数
int sm[N*4],mn[N*4],lz[N*4];
void pushup(int i){
mn[i]=min(mn[ls],mn[rs]);
if(mn[ls]==mn[rs]){
sm[i]=sm[ls]+sm[rs];
}else if(mn[ls]<mn[rs]){
sm[i]=sm[ls];
}else{
sm[i]=sm[rs];
}
}
void pushdown(int i){
if(lz[i]){
lz[ls]+=lz[i];
lz[rs]+=lz[i];
mn[ls]+=lz[i];
mn[rs]+=lz[i];
lz[i]=0;
}
}
void build(int i,int l,int r){
lz[i]=0;
if(l==r){
mn[i]=INF;
sm[i]=0;
return;
}
build(ls,l,mid);
build(rs,mid+1,r);
pushup(i);
}
//单点插入/修改,即开始增加以p为左端点的区间贡献
void insert(int i,int l,int r,int p){
if(l==r){
//此时以p为左端点的区间只有[p,p],因此mx-mn-cnt=-1,为合法区间
mn[i]=-1;
sm[i]=1;
return;
}
pushdown(i);
if(p<=mid){
insert(ls,l,mid,p);
}else{
insert(rs,mid+1,r,p);
}
pushup(i);
}
//区间更新(mx-mn-cnt)
void update(int i,int l,int r,int ql,int qr,int v){
if(ql<=l && qr>=r){
lz[i]+=v;
mn[i]+=v;
return;
}
pushdown(i);
if(ql<=mid){
update(ls,l,mid,ql,qr,v);
}
if(qr>mid){
update(rs,mid+1,r,ql,qr,v);
}
pushup(i);
}
}ac;
map<int,int> lst;
int smx[N],smn[N];
int main(){
// freopen("in.txt","r",stdin);
scanf("%d",&T);
for(int cas=1;cas<=T;cas++){
ll ans=0;
scanf("%d",&n);
ac.build(1,1,n);
lst.clear();
int mxt=0,mnt=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
ac.insert(1,1,n,i);
//单调栈维护最大最小值区间
//维护一个小顶栈,那么弹出来的元素作为最大值延伸的位置是[smx[mxt-1]+1,smx[mxt]]
while(mxt>0 && a[smx[mxt]]<=a[i]){
ac.update(1,1,n,smx[mxt-1]+1,smx[mxt],a[i]-a[smx[mxt]]);
mxt--;
}
smx[++mxt]=i;
while(mnt>0 && a[smn[mnt]]>=a[i]){
ac.update(1,1,n,smn[mnt-1]+1,smn[mnt],-(a[i]-a[smn[mnt]]));
mnt--;
}
smn[++mnt]=i;
//map维护上一次出现位置
int L=0;
if(lst.find(a[i])!=lst.end()){
L=lst[a[i]]+1;
}else{
L=1;
}
if(L<=i-1){
//比如3 1 2 4 3,最新加入的3,所以[1 2 4 3],[2 4 3],[4 3]都应该更新不同数的个数
//由于维护的是mx-mn-cnt,所以是-1
ac.update(1,1,n,L,i-1,-1);
}
lst[a[i]]=i;
//以当前a[i]为右端点元素的合法区间个数
//因为加入新节点(R,R)后,mn[1]肯定为-1,所以无需判断
ans+=1ll*ac.sm[1];
}
printf("Case #%d: %lld\n",cas,ans);
}
}
2018icpc宁夏邀请赛_L_Continuous Intervals的更多相关文章
- 2018宁夏邀请赛 Continuous Intervals(单调栈 线段树
https://vjudge.net/problem/Gym-102222L 题意:给你n个数的序列,让判断有几个区间满足排完序后相邻两数差都不大于1. 题解:对于一个区间 [L,R],记最大值为 m ...
- 2018icpc宁夏邀请赛网络赛_G_Trouble of Tyrant
题意 一列\(n\)个点,给定一个特殊的图,有两种边\(E(1,i)\)和\(E(i-1,i)\),多个询问,每次给一个\(d\),求所有路径长度加上\(d\)后1到\(n\)的最短路. 分析 首先这 ...
- 2018宁夏邀请赛 L Continuous Intervals(单调栈+线段树)
2018宁夏邀请赛 L Continuous Intervals(单调栈+线段树) 传送门:https://nanti.jisuanke.com/t/41296 题意: 给一个数列A 问在数列A中有多 ...
- [ICPC 2018 宁夏邀请赛] A-Maximum Element In A Stack(思维)
>传送门< 前言 辣鸡网络赛,虽然我是个菜鸡,然而好几个队伍十几分钟就AK???我心态那会彻底崩了,后来群里炸了,话题直接上知乎热搜,都是2018ICPC宁夏网络赛原题,这怎么玩,拼手速? ...
- 2018宁夏邀请赛L Continuous Intervals
题目链接:https://nanti.jisuanke.com/t/28412 题意: 给出n个数的序列.问序列中有多少个区间满足,排序完之后任意两个相邻的数之差不大于1. 题解: 用max表示区间最 ...
- 2018宁夏邀请赛 L. Continuous Intervals
转化一下询问即为区间$max - min + 1 = cnt$,其中$cnt$表示区间内数的种类数. 即求有多少区间$max - min - cnt=-1$,注意到任意区间的$max-min-cnt ...
- 2018acm-icpc宁夏邀请赛后记
由于要准备期末考试的缘故,时隔一个月之后我才想起来还有一场比赛没有总结. 大概是出去过的最远的地方了,宁夏理工学院离杭州有两千多千米. 不得不说感到了主办方满满的诚意,虽然是第一次办比赛,但是第一天组 ...
- 2018宁夏邀请赛网赛 I. Reversion Count(java练习题)
题目链接 :https://nanti.jisuanke.com/t/26217 Description: There is a positive integer X, X's reversion c ...
- “2018宁夏邀请赛 ” 兼 “The 2019 Asia Yinchuan First Round Online Programming”
------------7题弟弟,被各位半小时13题的大佬打惨了(滑稽)---------- 签到题就不写了. F :Moving On (1247ms) 题意:给定大小为N的带 ...
随机推荐
- js获取iframe里面的dom
最近在写页面遇到了问题,一个dom好多地方用到,然后我就单独写了个html页面,然后用iframe引入,但是,想获取iframe里面input的value,获取不到input,后面才知道原来js不能直 ...
- oracle(转)
Oracle数据库基本操作 1.概述 Oracle数据库客户端一般需要安装在服务器上,可以在服务器端操作,一般我们可以用sql developer工具远程连接到数据库,先行建立数据库,然后对表进行增删 ...
- Unity3D_(游戏)卡牌02_主菜单界面
启动屏界面.主菜单界面.选关界面.游戏界面 卡牌01_启动屏界面 传送门 卡牌02_主菜单界面 传送门 卡牌03_选关界面 传送门 卡牌04_游戏界面 传送门 主菜单界面 (选择左边图标或选 ...
- Unity3D_(Shuriken粒子系统)制作简单的烟花爆炸效果
Unity中的粒子系统可以用于制作特效,如开枪火花效果,简单爆炸效果等.(毕竟程序员不是设计师,简单的特效都没有问题,要制作一些非常美观的特效还是需要多了解跟美术有关的知识.) 粒子系统实现一个简单的 ...
- hive 调优(三)tez优化
我们采用亚马逊emr构建的集群,用hive查询的时候报错,FAILED: Execution Error, return code 2 from org.apache.hadoop.hive.ql.e ...
- Java使用FileOutputStream写入文件
From: http://beginnersbook.com/2014/01/how-to-write-to-a-file-in-java-using-fileoutputstream/ /* 使用F ...
- note:memcache 調試遇到的一些問題
1. gdb調試時提示:<value optimized out> ,原因是memcache的編譯选项做了优化,修改configure中CFLAGS中的-O3为-O0,可以解决gdb调试过 ...
- 第五周作业,LVM和TCP
1.磁盘lvm管理,完成下面要求,并写出详细过程: 1) 创建一个至少有两个PV组成的大小为20G的名为testvg的VG;要求PE大小 为16MB, 而后在卷组中创建大小为5G的逻辑卷testlv; ...
- [Nova] Failed to get shared "write" lock Is another process using the image?
目录 文章目录 目录 问题 解决 问题 [root@overcloud-compute-0 ~]# /usr/bin/python2 -m oslo_concurrency.prlimit --as= ...
- Idea创建项目后,提交项目到码云的问题
1.创建git仓库:vcs->import int version control->Create git repository 2.在项目头点击右键->git->add 3. ...