2018ICPC银川 L Continuous Intervals 单调栈 线段树
题意:给你一个序列,问你这个序列有多少个子区间,满足把区间里的数排序之后相邻两个数之间的差 <= 1 ?
思路:https://blog.csdn.net/u013534123/article/details/81164504
代码:
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define ls (o << 1)
#define rs (o << 1 | 1)
#define pii pair<int, int>
#define LL long long
using namespace std;
const int maxn = 100010;
map<int, int> last;
struct node {
int mi, add, cnt;
};
node tr[maxn * 4];
void maintain(pii& t1, pii t2) {
if(t1.first > t2.first) {
t1 = t2;
} else {
t1.second += t2.second;
}
}
void pushup(int o) {
if(tr[ls].mi < tr[rs].mi) {
tr[o].mi = tr[ls].mi;
tr[o].cnt = tr[ls].cnt;
} else if(tr[ls].mi > tr[rs].mi) {
tr[o].mi = tr[rs].mi;
tr[o].cnt = tr[rs].cnt;
} else {
tr[o].mi = tr[ls].mi;
tr[o].cnt = tr[ls].cnt + tr[rs].cnt;
}
}
void pushdown(int o) {
if(tr[o].add) {
tr[ls].mi += tr[o].add;
tr[ls].add += tr[o].add;
tr[rs].add += tr[o].add;
tr[rs].mi += tr[o].add;
tr[o].add = 0;
}
}
void build(int o, int l, int r) {
tr[o].mi = tr[o].add = tr[o].cnt = 0;
if(l == r) {
tr[o].cnt = 1;
return;
}
int mid = (l + r) >> 1;
build(ls, l, mid);
build(rs, mid + 1, r);
pushup(o);
}
void update(int o, int l, int r, int ql, int qr, int val) {
if(l >= ql && r <= qr) {
tr[o].add += val;
tr[o].mi += val;
return;
}
pushdown(o);
int mid = (l + r) >> 1;
if(ql <= mid) update(ls, l, mid, ql, qr, val);
if(qr > mid) update(rs, mid + 1, r, ql, qr, val);
pushup(o);
}
pii query(int o, int l, int r, int ql, int qr) {
if(l >= ql && r <= qr) {
return make_pair(tr[o].mi, tr[o].cnt);
}
int mid = (l + r) >> 1;
pushdown(o);
pii ans = make_pair(INF, 0);
if(ql <= mid) maintain(ans, query(ls, l, mid, ql, qr));
if(qr > mid) maintain(ans, query(rs, mid + 1, r, ql, qr));
return ans;
}
stack<int> mi, mx;
int a[maxn];
int main() {
int T, n;
LL ans = 0;
int kase = 0;
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
}
// memset(tr, 0, sizeof(tr));
build(1, 1, n);
last.clear();
ans = 0;
while(mi.size())mi.pop();
while(mx.size())mx.pop();
mx.push(0), mi.push(0);
for (int i = 1; i <= n; i++) {
// update(1, 1, n, i, i, a[i]);
int now = i - 1;
while(mx.size() > 1 && a[mx.top()] <= a[i]) {
int tmp = mx.top();
mx.pop();
update(1, 1, n, mx.top() + 1, now, a[i] - a[tmp]);
now = mx.top();
}
mx.push(i);
// update(1, 1, n, i, i, -a[i]);
now = i - 1;
while(mi.size() > 1 && a[mi.top()] >= a[i]) {
int tmp = mi.top();
mi.pop();
update(1, 1, n, mi.top() + 1, now, a[tmp] - a[i]);
now = mi.top();
}
mi.push(i);
update(1, 1, n, last[a[i]] + 1, i, -1);
last[a[i]] = i;
pii tmp = query(1, 1, n, 1, i);
if(tmp.first == -1) {
ans += tmp.second;
}
}
printf("Case #%d: %lld\n", ++kase, ans);
}
}
2018ICPC银川 L Continuous Intervals 单调栈 线段树的更多相关文章
- 2018宁夏邀请赛 L Continuous Intervals(单调栈+线段树)
2018宁夏邀请赛 L Continuous Intervals(单调栈+线段树) 传送门:https://nanti.jisuanke.com/t/41296 题意: 给一个数列A 问在数列A中有多 ...
- 洛谷P4198 楼房重建 单调栈+线段树
正解:单调栈+线段树 解题报告: 传送门! 首先考虑不修改的话就是个单调栈板子题昂,这个就是 然后这题的话,,,我怎么记得之前考试好像有次考到了类似的题目昂,,,?反正我总觉着这方法似曾相识的样子,, ...
- 2018宁夏邀请赛 Continuous Intervals(单调栈 线段树
https://vjudge.net/problem/Gym-102222L 题意:给你n个数的序列,让判断有几个区间满足排完序后相邻两数差都不大于1. 题解:对于一个区间 [L,R],记最大值为 m ...
- 南昌邀请赛I.Max answer 单调栈+线段树
题目链接:https://nanti.jisuanke.com/t/38228 Alice has a magic array. She suggests that the value of a in ...
- 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\}\).你需要从该序列中选出两个非空的子段,这两个子段满足 两个子段非包含关系. 两个子段存在交. 位于两个子段交中的元素在每个子段中只能出现 ...
- 【CF671E】Organizing a Race 单调栈+线段树
[CF671E]Organizing a Race 题意:n个城市排成一排,每个城市内都有一个加油站,赛车每次经过第i个城市时都会获得$g_i$升油.相邻两个城市之间由道路连接,第i个城市和第i+1个 ...
随机推荐
- Codeforces Round #369 (Div. 2) A. Bus to Udayland (水题)
Bus to Udayland 题目链接: http://codeforces.com/contest/711/problem/A Description ZS the Coder and Chris ...
- [CSP-S模拟测试]:模板(ac)(线段树启发式合并)
题目描述 辣鸡$ljh\ NOI$之后就退役了,然后就滚去学文化课了.他每天都被$katarina$大神虐,仗着自己学过一些姿势就给$katarina$大神出了一道题.有一棵$n$个节点的以$1$号节 ...
- MySQL高可用架构之MySQL5.7.19 PXC
CentOS7.3下Percona-XtraDB-Cluster-5.7.19集群部署PXC三节点安装:node1:10.10.10.11 node2:10.10.10.12node3:10.10.1 ...
- JQuery ajax 滚动底部加载更多
<%@ Page Language="C#" %> <%@ Import Namespace="System.IO" %> <%@ ...
- 阶段1 语言基础+高级_1-3-Java语言高级_1-常用API_1_第3节 Random类_11-练习二_猜数字小游
0到100之间的数字.猜多少次才能猜对最终的结果.大了或者小了都会告诉你. 二分法查找. 循环次数不确定用whilte true的方式去循环 前两种情况是需要重试的 把猜测的代码放在whilte循环里 ...
- 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_01 File类_4_File类的构造方法
学习一个类先学习构造方法和静态方法 重写了Object类的toString方法 文件夹结尾 相对路径 第二个构造方法 两个路径组装到了一起 加上双斜线 换成d盘 第三个构造 第一个参数是一个File对 ...
- pthon之mock应用
研发过程中常见分工合作开发接口,但互相之间接口有依赖,这时候便可以使用mock 目录 1.安装 2.使用mock调试自己写的方法 3.使用mock解除依赖关系 1.安装 由于我的是python2.7, ...
- js(javascript)取float型小数点后两位数的方法
以下我们将为大家介绍 JavaScript 保留两位小数的实现方法:四舍五入以下处理结果会四舍五入: ? 1 2 var num =2.446242342; num = num.toFixed(2); ...
- bash shell:获取当前脚本的绝对路径(pwd/readlink)
有时候,我们需要知道当前执行的输出shell脚本的所在绝对路径,可以用dirname实现. 我们知道 dirname 可以获取一个文件所在的路径,dirname的用处是: 输出已经去除了尾部的”/”字 ...
- layui基本使用(动态获取数据,并把需要的数据传到新打开的窗口)
<div class="xiaoxi">\n' + ' <div class="layui-row">\n' + ' <input ...