给你一个序列,给你m个区间,你可以选择其中的若干区间进行区间-1操作,每个区间只能选一次,问你最后整个的序列的最大值-最小值的差值最大为多少。
题意和E1一样 就是n变成了 1e5 那么我们就不能像E1一样使用 n^2 * m的算法了
我们考虑一下这个问题 E1是 n^2的枚举最小值
我们E2也是去枚举最小值 我们发现如果最大值和最小值都在一个区间内 你操作这个区间也就是区间减1是不会对答案产生影响的
如果最小值在 最大值不在 那么操作这个区间会使得答案 + 1
如果最大值在 最小值不在 那么操作这个区间会使得答案 - 1
所以实际上就是让你操作包含这个最小值位置 的 区间 注意一定不能二维排序 因为可能不满足 或者满足了我是用双指针就WA 13了
这样的话你建立两个vector 一个存以 i 开始的那个区间的右端
一个存以 i 为右端点的那个区间的左端
那么就可以枚举的方法做出答案了
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <stack>
#include <cmath>
#include <map>
#include <set>
#include <sstream>
#include <vector>
#include <stdlib.h>
#include <algorithm>
using namespace std;
#define dbg2(x1,x2) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<endl
#define dbg3(x1,x2,x3) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<" "<<#x3<<" = "<<x3<<endl
const int MAX_N = 100025;
queue<int > anss,tmp;
vector<int > st[MAX_N],ed[MAX_N];
int arr[MAX_N];
int maxx[MAX_N<<2],col[MAX_N<<2];
struct node
{
int l,r;
}Q[MAX_N];
void up(int rt)
{
maxx[rt] = max(maxx[rt<<1],maxx[rt<<1|1]);
}
void down(int rt,int l,int r)
{
if(col[rt])
{
int mid = (l+r)>>1;
col[rt<<1] += col[rt];
col[rt<<1|1] += col[rt];
maxx[rt<<1] += col[rt];
maxx[rt<<1|1] += col[rt];
col[rt] = 0;
}
}
void build(int rt,int l,int r)
{
col[rt] = 0;
if(l==r)
{
scanf("%d",&maxx[rt]);
return ;
}
int mid = (l+r)>>1;
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
up(rt);
}
void update(int rt,int l,int r,int x,int y,int v)
{
if(x<=l&&r<=y)
{
col[rt] += v;
maxx[rt] += v;
return ;
}
down(rt,l,r);
int mid = (l+r)>>1;
if(x<=mid) update(rt<<1,l,mid,x,y,v);
if(mid<y) update(rt<<1|1,mid+1,r,x,y,v);
up(rt);
}
int query(int rt,int l,int r,int x,int y)
{
if(x<=l&&r<=y)
{
return maxx[rt];
}
int mid = (l+r)>>1,maxx1 = -10000000,maxx2 = -10000000;
down(rt,l,r);
if(x<=mid) maxx1 = query(rt<<1,l,mid,x,y);
if(mid<y) maxx2 = query(rt<<1|1,mid+1,r,x,y);
return max(maxx1,maxx2);
}
int main()
{
int n,m,xb,ans = -1,maxx_ = -10000000,minn = 10000000,a,b;
scanf("%d%d",&n,&m);
build(1,1,n);
for(int i = 1;i<=m;++i)
{
scanf("%d%d",&Q[i].l,&Q[i].r);
st[Q[i].l].push_back(Q[i].r);
ed[Q[i].r].push_back(Q[i].l);
}
for(int i = 1;i<=n;++i)
{
for(int j = 0;j<st[i].size();j++)
update(1,1,n,i,st[i][j],-1);
int tmp = query(1,1,n,1,n) - query(1,1,n,i,i);
if(ans<tmp)
{
ans = tmp;
xb = i;
}
for(int j = 0;j<ed[i].size();j++)
update(1,1,n,ed[i][j],i,1);
}
for(int i = 1;i<=m;++i)
if(Q[i].l<=xb&&Q[i].r>=xb) anss.push(i);
printf("%d\n",ans);
printf("%d\n",anss.size());
int sz = anss.size();
for(int i = 1;i<=sz;++i)
{
int now = anss.front();
printf("%d",now);
anss.pop();
i==sz?printf("\n"):printf(" ");
}
return 0;
}