转化一下询问即为区间$max - min + 1 = cnt$,其中$cnt$表示区间内数的种类数。

即求有多少区间$max - min - cnt=-1$,注意到任意区间的$max-min-cnt \geq -1$,那么即维护区间$max-min-cnt$的最小值和最小值的个数,再看最小值等不等于$-1$就行了。

那么可以用扫描线扫右端点$r$,线段树维护左端点为$1, 2,\dots,r-1$的区间最小值和最小值的个数。每加入一个数,$r$这里必定为$-1$,所以当前区间最小值的个数就是答案了。

对于区间种类数就$[last[a[i]], i - 1]$多了$1$,那么要减去$1$,因为在式子里$cnt$,前面是负号。

然后最大值最小值就用两个单调栈搞一下就好了。区间加上对应的差值即可。

#include <bits/stdc++.h>
#define ll long long
using namespace std; const int N = 1e5 + ;
int top1, top2, a[N], st1[N], st2[N];
map<int, int> pos; struct Seg {
#define lp p << 1
#define rp p << 1 | 1
int tree[N << ], lazy[N << ], sum[N << ];
inline void init() {
memset(tree, , sizeof(tree));
memset(lazy, , sizeof(lazy));
memset(sum, 0x3f, sizeof(sum));
}
inline void pushdown(int p) {
if (lazy[p] == ) return;
lazy[lp] += lazy[p];
lazy[rp] += lazy[p];
sum[lp] += lazy[p];
sum[rp] += lazy[p];
lazy[p] = ;
}
inline void pushup(int p) {
sum[p] = min(sum[lp], sum[rp]);
if (sum[lp] == sum[rp]) tree[p] = tree[lp] + tree[rp];
else if (sum[lp] < sum[rp]) tree[p] = tree[lp];
else tree[p] = tree[rp];
}
void update(int p, int l, int r, int pos) {
if (l == r) {
tree[p] = ;
sum[p] = -;
return;
}
pushdown(p);
int mid = l + r >> ;
if (pos <= mid) update(lp, l, mid, pos);
else update(rp, mid + , r, pos);
pushup(p);
}
void update(int p, int l, int r, int x, int y, int val) {
if (x > y) return;
if (x <= l && y >= r) {
sum[p] += val;
lazy[p] += val;
return;
}
pushdown(p);
int mid = l + r >> ;
if (x <= mid) update(lp, l, mid, x, y, val);
if (y > mid) update(rp, mid + , r, x, y, val);
pushup(p);
}
} seg; inline void init() {
top1 = top2 = ;
seg.init();
pos.clear();
} int main() {
int T;
int kase = ;
scanf("%d", &T);
while (T--) {
init();
ll ans = ;
int n;
scanf("%d", &n);
for (int i = ; i <= n; i++) {
seg.update(, , n, i);
scanf("%d", &a[i]);
while (top1 && a[st1[top1]] <= a[i]) {
int p = st1[top1], key = a[st1[top1]];
top1--;
seg.update(, , n, st1[top1] + , p, a[i] - key);
}
st1[++top1] = i;
while (top2 && a[st2[top2]] >= a[i]) {
int p = st2[top2], key = a[st2[top2]];
top2--;
seg.update(, , n, st2[top2] + , p, key - a[i]);
}
st2[++top2] = i;
int l = pos[a[i]];
seg.update(, , n, l + , i - , -);
pos[a[i]] = i;
ans += seg.tree[];
}
printf("Case #%d: %lld\n", ++kase, ans);
}
return ;
}

2018宁夏邀请赛 L. Continuous Intervals的更多相关文章

  1. 2018宁夏邀请赛 L Continuous Intervals(单调栈+线段树)

    2018宁夏邀请赛 L Continuous Intervals(单调栈+线段树) 传送门:https://nanti.jisuanke.com/t/41296 题意: 给一个数列A 问在数列A中有多 ...

  2. 2018宁夏邀请赛L Continuous Intervals

    题目链接:https://nanti.jisuanke.com/t/28412 题意: 给出n个数的序列.问序列中有多少个区间满足,排序完之后任意两个相邻的数之差不大于1. 题解: 用max表示区间最 ...

  3. “2018宁夏邀请赛 ” 兼 “The 2019 Asia Yinchuan First Round Online Programming”

    ------------7题弟弟,被各位半小时13题的大佬打惨了(滑稽)---------- 签到题就不写了. F :Moving On            (1247ms) 题意:给定大小为N的带 ...

  4. 2018宁夏邀请赛 Continuous Intervals(单调栈 线段树

    https://vjudge.net/problem/Gym-102222L 题意:给你n个数的序列,让判断有几个区间满足排完序后相邻两数差都不大于1. 题解:对于一个区间 [L,R],记最大值为 m ...

  5. 2018宁夏邀请赛网赛 I. Reversion Count(java练习题)

    题目链接 :https://nanti.jisuanke.com/t/26217 Description: There is a positive integer X, X's reversion c ...

  6. 2018宁夏邀请赛K Vertex Covers

    题目链接:https://nanti.jisuanke.com/t/28411 题意: 给出n(n<=36)个点的一个图.求点覆盖集数. 题解: 将n个点折半为L和R两部分.对于R内部的边,枚举 ...

  7. 2018宁夏邀请赛G(DFS,动态规划【VECTOR<PAIR>】)

    //代码跑的很慢四秒会超时,结尾附两秒代码(标程) #include<bits/stdc++.h>using namespace std;typedef long long ll;cons ...

  8. 2018宁夏邀请赛K题Vertex Covers(高维前缀和 状压 折半

    https://vjudge.net/problem/Gym-102222K 题意:给定N点M边的无向图,每个点有点权.  点覆盖表示某个点集S{}覆盖了所有的边,其贡献是S中点权之积. 现在让你求所 ...

  9. 2018ICPC银川 L Continuous Intervals 单调栈 线段树

    题意:给你一个序列,问你这个序列有多少个子区间,满足把区间里的数排序之后相邻两个数之间的差 <= 1 ? 思路:https://blog.csdn.net/u013534123/article/ ...

随机推荐

  1. EXT.net 1.x TreePanel的一个坑

    Ext.net TreePanel有一个方法 drptreepanel.setChecked({ ids: idsarray, silent: true });  如果TreePanel里有1,3两个 ...

  2. Sitecore 9 为什么数据驱动的组织选择它

    Sitecore 9使用个性化和机器学习来帮助客户提高数字营销对数字投资的回报 Sitecore 9比以往任何时候都更加智能.主要功能包括: 数据集中化 向后兼容性 简单的迁移 该平台简化了营销人员和 ...

  3. springmvc流程图以及配置

    springmvc:是完成数据的封装和跳转的功能 流程图如下: springmvc的配置流程 1.导入jar包 二.配置servlet文件 init-param的作用是在启动servlet启动时规定其 ...

  4. vue的package.json文件理解

    参考文档: https://www.cnblogs.com/tzyy/p/5193811.html#_h1_0 https://www.cnblogs.com/hongdiandian/p/83210 ...

  5. map集合转set集合

    import java.util.*; //Map集合的迭代器输出,先将Map集合变为Set集合,再使用Iterator迭代器 public class Java_collection { publi ...

  6. MVC伪静态路由简单搭配

      public static void RegisterRoutes(RouteCollection routes)         {             routes.IgnoreRoute ...

  7. 【转】socket通信-C#实现tcp收发图片音视频等字节流数据

    在日常碰到的项目中,经常碰到需要收发二进制数据的场景.比如要发送一张图片,要发送一首音频,要发送一个压缩包,要发送一个视频等等.这些数据并非字符串,而是二进制字节流数据.那么如何如何使用SharpSo ...

  8. jQuery---bootstrap的下载使用,栅格(12个格子),轮播图,矢量图字体图标,进度条,选项卡,标签,表达校验

    jQuery---bootstrap的下载使用,栅格(12个格子),轮播图,矢量图字体图标,进度条,选项卡,标签,表达校验 一丶bootstrap的使用 下载资源文件: bootstrap官网 导入 ...

  9. 18、git提交代码并将develop分支合并到master分支上

    提交合并代码流程: git add .git commit -m ''git pushgit checkout mastergit merge develop //将develop 分支与master ...

  10. Java 之 ArrayList 集合

    一.ArrayList 概述 java.util.ArrayList  是 大小可变的数组 的实现,存储在内的数据称为元素.该类是一个 集合类(容器),可以让我们更便捷的存储和操作对象数据. 该类可以 ...