一个区间为好区间当且仅当$\max_{l\le i\le r}a_{i}-\min_{l\le i\le r}a_{i}=r-l$,考虑固定右端点$r$,维护所有左端点$l$的上述式子左-右的值,那么答案即求0的个数,也就是最小值的个数(该值必然非负且$l=r$时必然为0)

如何维护右端点移动:先将所有位置减1,再用单调栈找到之前第一个小于和大于其的位置,然后由于这两个位置中必然有一个为$r-1$,不需要考虑,记剩下的位置为$x$,不妨假设$a_{x}>a_{r}$

那么也就是考虑以$a[1..r]$这个前缀的后缀最大值,也即单调栈中被$r$弹出的元素,因此对于被弹出的两个元素中间,加上$a_{r}-先弹出的元素$即可($a_{x}<a_{r}$类似)

对于多组询问,将询问离线并记录在对应位置上,即查询区间$[l,r]$最小值次数(令未修改的位置为1)

维护一个时间标记,表示当前的sum已经统计到该时间,再下传修改同时也要下传时间标记,因此在上一个时间标记到现在其最小值次数不变,即可维护

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 120005
4 #define ll long long
5 #define L (k<<1)
6 #define R (L+1)
7 #define mid (l+r>>1)
8 vector<pair<int,int> >v[N];
9 int n,m,x,y,a[N],mn[N],mx[N],f[N<<2],tag[N<<2],tim[N<<2],tot[N<<2];
10 ll ans[N],sum[N<<2];
11 void upd(int k,int x){
12 f[k]+=x;
13 tag[k]+=x;
14 }
15 void upd_time(int k,int x){
16 sum[k]+=1LL*x*tot[k];
17 tim[k]+=x;
18 }
19 void up(int k){
20 f[k]=min(f[L],f[R]);
21 tot[k]=0;
22 if (f[k]==f[L])tot[k]+=tot[L];
23 if (f[k]==f[R])tot[k]+=tot[R];
24 sum[k]=sum[L]+sum[R];
25 }
26 void down(int k){
27 upd(L,tag[k]);
28 upd(R,tag[k]);
29 tag[k]=0;
30 if (f[L]==f[k])upd_time(L,tim[k]);
31 if (f[R]==f[k])upd_time(R,tim[k]);
32 tim[k]=0;
33 }
34 void build(int k,int l,int r){
35 f[k]=1;
36 tot[k]=r-l+1;
37 if (l==r)return;
38 build(L,l,mid);
39 build(R,mid+1,r);
40 }
41 void update(int k,int l,int r,int x,int y,int z){
42 if ((l>y)||(x>r))return;
43 if ((x<=l)&&(r<=y)){
44 upd(k,z);
45 return;
46 }
47 down(k);
48 update(L,l,mid,x,y,z);
49 update(R,mid+1,r,x,y,z);
50 up(k);
51 }
52 ll query(int k,int l,int r,int x,int y){
53 if ((l>y)||(x>r))return 0;
54 if ((x<=l)&&(r<=y))return sum[k];
55 down(k);
56 return query(L,l,mid,x,y)+query(R,mid+1,r,x,y);
57 }
58 int main(){
59 scanf("%d",&n);
60 for(int i=1;i<=n;i++)scanf("%d",&a[i]);
61 scanf("%d",&m);
62 for(int i=1;i<=m;i++){
63 scanf("%d%d",&x,&y);
64 v[y].push_back(make_pair(x,i));
65 }
66 build(1,1,n);
67 for(int i=1;i<=n;i++){
68 update(1,1,n,1,i,-1);
69 while ((mn[0])&&(a[mn[mn[0]]]>a[i])){
70 if (mn[0]==1)update(1,1,n,1,mn[mn[0]],a[mn[mn[0]]]-a[i]);
71 else update(1,1,n,mn[mn[0]-1]+1,mn[mn[0]],a[mn[mn[0]]]-a[i]);
72 mn[0]--;
73 }
74 mn[++mn[0]]=i;
75 while ((mx[0])&&(a[mx[mx[0]]]<a[i])){
76 if (mx[0]==1)update(1,1,n,1,mx[mx[0]],a[i]-a[mx[mx[0]]]);
77 else update(1,1,n,mx[mx[0]-1]+1,mx[mx[0]],a[i]-a[mx[mx[0]]]);
78 mx[0]--;
79 }
80 mx[++mx[0]]=i;
81 upd_time(1,1);
82 for(int j=0;j<v[i].size();j++)ans[v[i][j].second]=query(1,1,n,v[i][j].first,i);
83 }
84 for(int i=1;i<=m;i++)printf("%lld\n",ans[i]);
85 }

[cf997E]Good Subsegments的更多相关文章

  1. 「CF997E」 Good Subsegments

    CF997E Good Subsegments 传送门 和 CF526F 差不多,只不过这道题是对多个子区间进行询问. 据说有一个叫析合树的东西可以在线做,不过有时间再说吧. 考虑离线询问,将每个询问 ...

  2. CF 997E 解题报告

    CF997E Good Subsegments 给你一个长度为\(n\)的排列 \(P\),定义一段子区间是好的,当且仅当这个子区间内的值构成了连续的一段.例如对于排列\(\{1,3,2\}\),\( ...

  3. 【CF997E】Good Subsegments (线段树+单调栈)

    Description 原题链接 给你一个长度为\(n\)的排列\(~P\),定义一段子区间是好的,当且仅当这个子区间内的值构成了连续的一段.例如对于排列\(\{1,3,2 \}\),\([1, 1] ...

  4. 题解 CF997E 【Good Subsegments】

    先将问题进行转化,发现满足\((max-min)-(r-l)=0\)的区间即为好区间. 对于本题这样的统计子区间的问题,先将询问离线,按右端点排序一个一个解决,固定右端点,然后通过数据结构来处理出区间 ...

  5. [CF997E] Good SubSegment

    Description Transmission Gate 给你一个长度为n的排列P,定义一段子区间是好的,当且仅当这个子区间内的值构成了连续的一段.例如对于排列\(\{1,3,2\}\),\([1, ...

  6. #C++初学记录(set进阶#acm cf 190802 B. Subsegments)

    B. Subsegments#set进阶 Programmer Sasha has recently begun to study data structures. His coach Stas to ...

  7. [STL] Codeforces 69E Subsegments

    Subsegments time limit per test 1 second memory limit per test 256 megabytes input standard input ou ...

  8. Sorted Subsegments

    https://www.hackerrank.com/contests/101hack38/challenges/sorted-subsegments/problem 首先要注意到可以二分答案,比如当 ...

  9. [cf 997 E] Good Subsegments

    (这是石神找到的一道hiao题.) 题意: 你有一个长度为n的排列,有Q组询问$[l,r]$,每次询问$[l,r]$的子区间中有多少是好的. 一个区间是好的区间当且仅当该区间中的元素在排序后是连续的. ...

随机推荐

  1. LightningChart XY功能中的常见问题

    LightningChart XY功能中的常见问题 XY 是LightningChart 的重要功能之一,也是被用户使用最广泛的.用户经常对这个功能有着这样那样的疑问,现在将一些常用问题汇总了一下,希 ...

  2. Multidimension Tools(多维工具)

    多维工具 # Process: 创建 NetCDF 栅格图层 arcpy.MakeNetCDFRasterLayer_md("", "", "&quo ...

  3. 从零到熟悉,带你掌握Python len() 函数的使用

    摘要:本文为你带来如何找到长度内置数据类型的使用len() 使用len()与第三方数据类型 提供用于支持len()与用户定义的类. 本文分享自华为云社区<在 Python 中使用 len() 函 ...

  4. ORA-19815: WARNING: db_recovery_file_dest_size闪回区爆满问题处理

    问题描述:有一个数据库起不来了,根据层层排查,是因为归档设置在了闪回区,文件的大小已经超出了闪回区限制.最后直接给数据库拖挂 环境:windows server2012 , oracle 19c,单机 ...

  5. 【UE4 C++ 基础知识】<10>资源的引用

    2种引用方式 硬引用(Hard Reference) 即对象 A 引用对象 B,并导致对象 B 在对象 A 加载时加载 硬引用过多会导致运行时很多暂时用不到的资源也被加载到内存中 大量资源会导致进程阻 ...

  6. .NET 事件总线,简化项目、类库、线程、服务等之间的通信,代码更少,质量更好。‎

    Jaina .NET 事件总线,简化项目.类库.线程.服务等之间的通信,代码更少,质量更好.‎ 安装 Package Manager Install-Package Jaina .NET CLI do ...

  7. 什么是关系图 (ERD)?

    首先,什么是实体关系图? 实体关系图,也称为ERD,ER图或ER模型,是一种用于数据库设计的结构图.一个ERD包含不同的符号和连接器,它们可视化两个重要信息:系统范围内的主要实体,以及这些实体之间的相 ...

  8. Java:动态代理小记

    Java:动态代理小记 对 Java 中的 动态代理,做一个微不足道的小小小小记 概述 动态代理:当想要给实现了某个接口的类中的方法,加一些额外的处理.比如说加日志,加事务等.可以给这个类创建一个代理 ...

  9. 【Linux命令063】Linux非常简单常用的入门命令

    Linux常用命令 这是一篇我在公众号上发布的文章,还算较为受欢迎. 博客园这边荒废好长时间了,主要是最近一年经常撰写的文章都是Linux相关的入门文章. 不知道是否能通过博客园的首页审核. 1.cd ...

  10. js this指向汇总

    this指向 普通函数  window 定时器函数         window 事件函数 事件源 箭头函数 父function中的this,没有就是window 对象函数 对象本身 构造函数 实例化 ...