CF1108E2 Array and Segments (Hard version)

题目传送门

思路

怎么会有题解是 \(O(n^2+nm)\) 的垃圾做法阿,这题可以直接线段树做。

考虑枚举一个点 \(i\),假如我们想要 \(i\) 点作为最小值,贪心地想,我们如果把所有包含 \(i\) 的区间选进去,那么结果一定不劣。

假设最大值位于点 \(j\),区间 \(k\) 包含了区间 \(i\)

那么我们可以分类讨论:

  • 区间 \(k\) 包含了点 \(j\),此时 \(a_i,a_j\) 一起减,答案不变。
  • 区间 \(k\) 未包含点 \(j\),此时仅有 \(a_i\) 会减,答案增大 \(1\)

总上所述,最有策略是选择所有包含点 \(i\) 的区间。

于是仅需一颗支持区间修改的线段树即可。

时间复杂度 \(O(n \log n+m \log n)\)

代码

#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;
}
posted @ 2022-11-08 13:52  Tx_Lcy  阅读(28)  评论(0)    收藏  举报