题意:给你一个序列,问你这个序列有多少个子区间,满足把区间里的数排序之后相邻两个数之间的差 <= 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);
}
}

  

最新文章

  1. Oracle 数据库知识汇总篇
  2. sql server2008根据经纬度计算两点之间的距离
  3. HTML5之文件API
  4. 新作《ASP.NET Web API 2框架揭秘》正式出版
  5. JAVA中SERIALVERSIONUID的解释
  6. Android_Fragment(碎片)知识点讲解
  7. Mini projects #8–RiceRocks
  8. list 集合
  9. How to (seriously) read a scientific paper
  10. Java NIO之选择器Selector
  11. [转]反向代理过程与Nginx特点详解
  12. [Practical Git] Filter commit history with git log arguments
  13. spoj cot: Count on a tree 主席树
  14. Unix/Linux环境C编程入门教程(38) shell命令进阶演示
  15. myeclipse中自己手动配置maven
  16. Xsser
  17. mysql 时间戳格式化函数FROM_UNIXTIME和UNIX_TIMESTAMP函数的使用说明
  18. 谷歌浏览器Chrome播放rtsp视频流解决方案
  19. 移动端(H5)弹框组件--简单--实用--不依赖jQuery
  20. 通用查询类封装之Mongodb篇

热门文章

  1. 3D Computer Grapihcs Using OpenGL - 09 Enable Depth Test
  2. [ethereum源码分析](4) ethereum运行开启console
  3. 《SQL Server 2012 T-SQL基础》读书笔记 - 9.事务和并发
  4. Hadoop 服务SYS CPU过高导致宕机问题
  5. Matlab 读取文件夹里所有的文件
  6. python twisted异步将数据导入到数据库中
  7. SQL*Plus 与数据库的交互
  8. jQ全选或取消全选
  9. oracle--单行函数和多行函数
  10. C++学习笔记(六)--结构体