线段树

对于$Easy$ $version$可以枚举极大值和极小值的位置,然后判断即可

但对于$Hard$ $version$明显暴力同时枚举极大值和极小值会超时

那么,考虑只枚举极小值

对于数轴上每一个点,记录开始和结束于这个点的区间

那么从1枚举到i时可以处理出当包含i点所有区间

所以用线段树维护修改这些区间,进行判断总区间的极差

记录最大值即可

#include <bits/stdc++.h>
using namespace std;
const int MAXN=1e5+100;
int n,m,a[MAXN],l[310],r[310];
int ans,wh;
vector <int> t,be[MAXN],ed[MAXN];
struct node
{
int l,r,MAX,MIN,sum,lazy;
}sh[MAXN*4];
void pushup(int x)
{
sh[x].sum=sh[x+x].sum+sh[x+x+1].sum;
sh[x].MAX=max(sh[x+x].MAX,sh[x+x+1].MAX);
sh[x].MIN=min(sh[x+x].MIN,sh[x+x+1].MIN);
}
void pushdown(int x)
{
if (sh[x].lazy!=0)
{
sh[x+x].lazy+=sh[x].lazy;
sh[x+x+1].lazy+=sh[x].lazy;
sh[x+x].sum+=sh[x].lazy;
sh[x+x].MAX+=sh[x].lazy;
sh[x+x].MIN+=sh[x].lazy;
sh[x+x+1].sum+=sh[x].lazy;
sh[x+x+1].MAX+=sh[x].lazy;
sh[x+x+1].MIN+=sh[x].lazy;
sh[x].lazy=0;
}
}
void build(int x,int ll,int rr)
{
sh[x].l=ll;
sh[x].r=rr;
if (ll==rr)
{
sh[x].MAX=sh[x].MIN=sh[x].sum=a[ll];
return;
}
int mid;
mid=(ll+rr)>>1;
build(x+x,ll,mid);
build(x+x+1,mid+1,rr);
pushup(x);
}
void change(int x,int ll,int rr,int k)//区间修改
{
if (sh[x].l>=ll && sh[x].r<=rr)
{
sh[x].sum+=k;
sh[x].MIN+=k;
sh[x].MAX+=k;
sh[x].lazy+=k;
return;
}
pushdown(x);
int mid;
mid=(sh[x].l+sh[x].r)>>1;
if (ll<=mid)
change(x+x,ll,rr,k);
if (rr>mid)
change(x+x+1,ll,rr,k);
pushup(x);
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);
for (int i=1;i<=m;i++)
scanf("%d%d",&l[i],&r[i]);
build(1,1,n);
if (n==1)
{
printf("0\n0\n");
return 0;
}
for (int i=1;i<=m;i++)
{
be[l[i]].push_back(i);//对于结束和开始的节点记录区间
ed[r[i]].push_back(i);
}
ans=sh[1].MAX-sh[1].MIN;
wh=0;
for (int i=1;i<=n;i++)
{
for (int j=0;j<(int)ed[i-1].size();j++)
{
int u;
u=ed[i-1][j];
change(1,l[u],r[u],1);//将之前修改的区间对当前无影响改回去
}
for (int j=0;j<(int)be[i].size();j++)
{
int u;
u=be[i][j];
change(1,l[u],r[u],-1);//将新增的区间修改
}
pushdown(1);
pushup(1);
if (sh[1].MAX-sh[1].MIN>ans)//记录当期的极差
{
ans=sh[1].MAX-sh[1].MIN;
wh=i;
}
}
for (int i=1;i<=m;i++)
{
if (l[i]<=wh && r[i]>=wh)
t.push_back(i);
}
printf("%d\n%d\n",ans,(int)t.size());
for (int i=0;i<(int)t.size();i++)
printf("%d ",t[i]);
printf("\n");
}

最新文章

  1. 初识 Html5
  2. CSS3--box-shadow
  3. Xcode导航栏不显示模拟器选择框ToolBar
  4. 怎么搭建Web Api
  5. poj 2503:Babelfish(字典树,经典题,字典翻译)
  6. Sprint总结和第八九十的读书笔记
  7. JDK自带工具一览表。妈妈再也不用担心你到处去下载小软件了~~
  8. 用c/c++混合编程方式为ios/android实现一个自绘日期选择控件(一)
  9. 微课程--Android--Android开发学习体系
  10. cojs 简单的最近公共祖先 解题报告
  11. 【网络流24题】No.19 负载平衡问题 (费用流)
  12. mongoose 查询子文档的方法
  13. 《JavaScript+DOM编程艺术》的摘要(五)-----添加insertAfter
  14. 无法识别的属性“targetFramework”。请注意,属性名是大写和小写。错误的解决方案
  15. Sass与Compress实战:第二章
  16. 【Electron】Electron开发入门(三):main process和web page 通信
  17. Luogu P3371 【模板】单源最短路径
  18. Flutter 初尝:从 Java 无缝过渡
  19. B+树介绍
  20. 结构化您的Python工程

热门文章

  1. Java知识系统回顾整理01基础04操作符07Scanner
  2. 【题解】CF413C Jeopardy!
  3. windows server2008 r2激活
  4. shell-变量的数值运算与特殊应用expr
  5. C语言实现表达式求值,支持+、-、*、/四则运算,并且支持多级括号,自定义了栈的操作。
  6. XUEXI0.4
  7. go panic
  8. Jquery特效之=》仿京东多条件筛选特效
  9. 第六章 SSH远程服务介绍
  10. CentOS 8 Yum安装ansible