枚举minn+维护变化+线段树区间最大
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
int n,m;
int a[100005];
int rg[305][2];
vector<int>in[100005],out[100005];
struct node
{
int l,r;
int fg,maxn;
}tr[100005*5];
node up(node rt,node ls,node rs)
{
node ntr=rt;
ntr.maxn=max(ls.maxn,rs.maxn);
return ntr;
}
void build(int i,int l,int r)
{
tr[i].l=l;tr[i].r=r;tr[i].fg=0;
if(l==r)
{
tr[i].maxn=a[l];
}
else
{
int mid=(l+r)/2;
build(i*2,l,mid);
build(i*2+1,mid+1,r);
tr[i]=up(tr[i],tr[i*2],tr[i*2+1]);
}
return ;
}
void down(int i)
{
if(tr[i].fg!=0)
{
tr[i*2].fg+=tr[i].fg;tr[i*2].maxn+=tr[i].fg;
tr[i*2+1].fg+=tr[i].fg;tr[i*2+1].maxn+=tr[i].fg;
tr[i].fg=0;
}
}
void update(int i,int l,int r,int ql,int qr,int w)
{
if(l==ql && r==qr)
{
tr[i].maxn+=w;tr[i].fg+=w;
}
else
{
down(i);
int mid=(l+r)/2;
if(qr<=mid)
update(i*2,l,mid,ql,qr,w);
else if(ql>mid)
update(i*2+1,mid+1,r,ql,qr,w);
else
{
update(i*2,l,mid,ql,mid,w);
update(i*2+1,mid+1,r,mid+1,qr,w);
}
tr[i]=up(tr[i],tr[i*2],tr[i*2+1]);
}
}
node query(int i,int l,int r,int ql,int qr)
{
if(l==ql && r==qr)
{
return tr[i];
}
else
{
down(i);
int mid=(l+r)/2;
if(qr<=mid)
return query(i*2,l,mid,ql,qr);
else if(ql>mid)
return query(i*2+1,mid+1,r,ql,qr);
else
{
node tp1=query(i*2,l,mid,ql,mid);
node tp2=query(i*2+1,mid+1,r,mid+1,qr);
node tp3=up(tp3,tp1,tp2);
return tp3;
}
}
}
int main() {
while(~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",&rg[i][0],&rg[i][1]),in[rg[i][0]].push_back(i),out[rg[i][1]+1].push_back(i);
int ansid=1,ans=0;
int sum=0;
build(1,1,n);
for(int i=1;i<=n;i++)
{
int len=in[i].size();
for(int j=0;j<len;j++)
{
int id=in[i][j];
int l=rg[id][0];
int r=rg[id][1];
update(1,1,n,l,r,-1);
sum--;
}
len=out[i].size();
for(int j=0;j<len;j++)
{
int id=out[i][j];
int l=rg[id][0];
int r=rg[id][1];
update(1,1,n,l,r,1);
sum++;
}
int maxn=query(1,1,n,1,n).maxn;
int tans=(maxn-(a[i]+sum));
if(tans>ans)
{
ans=tans;ansid=i;
}
}
printf("%d\n",ans);
int ct=0;int anss[305];
for(int i=1;i<=m;i++)
{
if(rg[i][0]<=ansid && rg[i][1]>=ansid)
{
anss[ct++]=i;
}
}
printf("%d\n",ct);
for(int i=0;i<ct;i++)
{
printf("%d ",anss[i]);
}
printf("\n");
}
return 0;
}