https://vjudge.net/problem/Gym-102222L

题意:给你n个数的序列,让判断有几个区间满足排完序后相邻两数差都不大于1。

题解:对于一个区间 [L,R],记最大值为 max、最小值为 min、数 字种类数为 cnt,那么这个区间是 continuous interval 当且 仅当 max−min+ 1 = cnt。 考虑从小到大枚举 R,用线段树维护每个 L 的区间 [L,R] 的 max−min−cnt 的值。 由于总有 max−min+1 ≥cnt,那么只需要维护线段树上每 个 L 对应的 max−min−cnt 的最小值,以及有多少个 L 取 到这个最小值。 当 R 变大时,每个 L 对应的三个值都需要进行修改。对于 max 和 min,可以用单调栈来维护后缀 max 和 min,然后在 线段树上进行区间加减操作,对于 cnt,只需要在线段树上 对区间 [lastai + 1,R] 进行加减操作。

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=2000010;
int Mn[maxn],lazy[maxn],sum[maxn],a[maxn];
int q1[maxn],t1,q2[maxn],t2;
map<int,int>mp;
void build(int Now,int L,int R)
{
sum[Now]=R-L+1; Mn[Now]=lazy[Now]=0;
if(L==R) return ; int Mid=(L+R)>>1;
build(Now<<1,L,Mid);
build(Now<<1|1,Mid+1,R);
}
void pushdown(int Now)
{
if(!lazy[Now]) return ;
Mn[Now<<1]+=lazy[Now]; Mn[Now<<1|1]+=lazy[Now];
lazy[Now<<1]+=lazy[Now]; lazy[Now<<1|1]+=lazy[Now];
lazy[Now]=0;
}
void pushup(int Now)
{
Mn[Now]=min(Mn[Now<<1],Mn[Now<<1|1]);
if(Mn[Now<<1]==Mn[Now<<1|1]) sum[Now]=sum[Now<<1]+sum[Now<<1|1];
else if(Mn[Now<<1]<Mn[Now<<1|1]) sum[Now]=sum[Now<<1];
else sum[Now]=sum[Now<<1|1];
}
void update(int Now,int L,int R,int l,int r,int v)
{
if(l>r) return ;
if(L==R) {
Mn[Now]+=v;
return ;
}
if(l<=L&&r>=R){
Mn[Now]+=v; lazy[Now]+=v;
return ;
}
int Mid=(L+R)>>1; pushdown(Now);
if(l<=Mid) update(Now<<1,L,Mid,l,r,v);
if(r>Mid) update(Now<<1|1,Mid+1,R,l,r,v);
pushup(Now);
}
int main()
{
int T,N,C=0; ll ans;
scanf("%d",&T);
while(T--){
scanf("%d",&N);
rep(i,1,N) scanf("%d",&a[i]);
build(1,1,N);
t1=t2=0; ans=0; mp.clear();
rep(i,1,N){
update(1,1,N,i,i,-1);
while(t1&&a[i]>=a[q1[t1]]){
update(1,1,N,q1[t1-1]+1,q1[t1],a[i]-a[q1[t1]]);
t1--;
}
q1[++t1]=i; //单减栈 while(t2&&a[i]<=a[q2[t2]]){
update(1,1,N,q2[t2-1]+1,q2[t2],a[q2[t2]]-a[i]);
t2--;
}
q2[++t2]=i; //单增栈 update(1,1,N,mp[a[i]]+1,i-1,-1); mp[a[i]]=i;
ans+=sum[1];
}
printf("Case #%d: %lld\n",++C,ans);
}
return 0;
}

最新文章

  1. Python 从零学起(纯基础) 笔记 之 迭代器、生成器和修饰器
  2. 微信连wifi正式全量对外开放申请 升级智能服务
  3. Objective-C中的Block(闭包) (轉載)
  4. 一步步学习NHibernate(1)&mdash;&mdash;NHibernate介绍
  5. Qt调用DLL
  6. VS路宏 vc++于OutDir、ProjectDir、SolutionDir不同的路径
  7. java中的异常处理机制
  8. Linux下安装php开发框架yaf
  9. IIS Express允许外部访问(外部调试)
  10. 【Linux】在Win10上搭建WSL(适用于Linux的Windows子系统)
  11. 读取gzmt.csv文件,计算均值及概率
  12. Web开发(XAMPP服务器搭建)
  13. zabbix通过agent添加监控项的步骤
  14. ant____&lt;project&gt;标签的使用与含义
  15. php中的正则函数:正则匹配,正则替换,正则分割 所有的操作都不会影响原来的字符串.
  16. 初识数据库、初识MySQL
  17. leetcode刷题笔记258 各位相加
  18. 在SQLite中使用事务
  19. JAVA中如何将一个json形式的字符串转为json对象或对象列表
  20. 【leetcode 桶排序】Maximum Gap

热门文章

  1. ESP-8266 RTOS 环境搭建
  2. 基于ReentrantLock的非公平锁理解AQS
  3. 深入理解java内存模型--读书笔记
  4. 算法与数据结构基础 - 哈希表(Hash Table)
  5. Fragment 使用详解
  6. Codeforces Round #527 (Div. 3) 总结 A B C D1 D2 F
  7. 编码规范 | Java函数优雅之道(上)
  8. ASP.NET Core MVC 之视图组件(View Component)
  9. 扩展欧几里德算法(递归及非递归实现c++版)
  10. 建立第一个G2图表