CF1108E2 Array and Segments (Hard version)
思路
怎么会有题解是
考虑枚举一个点
假设最大值位于点
那么我们可以分类讨论:
- 区间
包含了点 ,此时 一起减,答案不变。 - 区间
未包含点 ,此时仅有 会减,答案增大 。
总上所述,最有策略是选择所有包含点
于是仅需一颗支持区间修改的线段树即可。
时间复杂度
代码
#include<bits/stdc++.h>
using namespace std;
int const N=1e5+10;
struct Segment_Tree{
#define ls (x<<1)
#define rs (x<<1|1)
#define mid ((l+r)>>1)
int minx[N<<2],maxx[N<<2],lazy[N<<2];
inline void pushdown(int x){
minx[ls]+=lazy[x];minx[rs]+=lazy[x];
maxx[ls]+=lazy[x];maxx[rs]+=lazy[x];
lazy[ls]+=lazy[x];lazy[rs]+=lazy[x];
lazy[x]=0;
}
inline void update(int x,int l,int r,int ll,int rr,int v){
if (ll<=l && r<=rr){minx[x]+=v,maxx[x]+=v,lazy[x]+=v;return;}
pushdown(x);
if (ll<=mid) update(ls,l,mid,ll,rr,v);
if (mid<rr) update(rs,mid+1,r,ll,rr,v);
minx[x]=min(minx[ls],minx[rs]);
maxx[x]=max(maxx[ls],maxx[rs]);
}
}T;
int a[N],xx[N],yy[N];
vector<int>b[N];
priority_queue< pair<int,int>,deque< pair<int,int> >,greater< pair<int,int> > >q;
signed main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
int n,m;cin>>n>>m;int x,y,ans=0,pl=0;
for (int i=1;i<=n;++i) cin>>a[i],T.update(1,1,n,i,i,a[i]);
for (int i=1;i<=m;++i) cin>>x>>y,b[x].push_back(y),xx[i]=x,yy[i]=y;
for (int i=1;i<=n;++i){
for (auto j:b[i]) T.update(1,1,n,i,j,-1),q.push({j,i});
while (!q.empty() && q.top().first<i) T.update(1,1,n,q.top().second,q.top().first,1),q.pop();
if (T.maxx[1]-T.minx[1]>ans) ans=T.maxx[1]-T.minx[1],pl=i;
}
cout<<ans<<'\n';
vector<int>Ans;
for (int i=1;i<=m;++i)
if (xx[i]<=pl && yy[i]>=pl) Ans.push_back(i);
cout<<(int)Ans.size()<<'\n';
for (auto i:Ans) cout<<i<<' ';
cout<<'\n';
return 0;
}
本文作者:Tx_Lcy
本文链接:https://www.cnblogs.com/tx-lcy/p/16869461.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步