经典套路题,发现l,r都在变,因此枚举r,找到最小的l即可
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<ll,int> pll; typedef pair<int,int> plll; const int N=2e5+10; const int inf=0x3f3f3f3f; struct node{ int l,r; ll mx; ll lazy; }tr[N<<2]; struct seg{ ll id,w; }; vector<seg> num[N]; ll n,k; plll res[N]; void build(int u,int l,int r){ if(l==r){ tr[u]={l,r,0,0}; } else{ tr[u]={l,r,0,0}; int mid=l+r>>1; build(u<<1,l,mid); build(u<<1|1,mid+1,r); } } void pushdown(int u){ ll x=tr[u].lazy; tr[u<<1].mx+=x; tr[u<<1|1].mx+=x; tr[u<<1].lazy+=x; tr[u<<1|1].lazy+=x; tr[u].lazy=0; } void pushup(int u){ tr[u].mx=max(tr[u<<1].mx,tr[u<<1|1].mx); } void modify(int u,int l,int r,ll x){ if(tr[u].l>=l&&tr[u].r<=r){ tr[u].mx+=x; tr[u].lazy+=x; return ; } if(tr[u].lazy) pushdown(u); int mid=tr[u].l+tr[u].r>>1; if(l<=mid) modify(u<<1,l,r,x); if(r>mid) modify(u<<1|1,l,r,x); pushup(u); } pll query(int u){ if(tr[u].l==tr[u].r){ return {tr[u].mx,tr[u].l}; } if(tr[u].lazy) pushdown(u); if(tr[u<<1].mx>=tr[u<<1|1].mx){ return query(u<<1); } else{ return query(u<<1|1); } } int main(){ ios::sync_with_stdio(false); cin>>n>>k; int i; ll mx=0; for(i=1;i<=n;i++){ int l,r; ll p; cin>>l>>r>>p; mx=max(mx,1ll*r); res[i]={l,r}; num[r].push_back({l,p}); } ll ans=0; build(1,1,mx); int l,r; for(i=1;i<=mx;i++){ modify(1,1,i,-k); for(auto t:num[i]){ modify(1,1,t.id,t.w); } auto t=query(1); if(t.first>ans){ ans=t.first; l=t.second,r=i; } } int sz=0; if(ans!=0){ for(i=1;i<=n;i++){ if(res[i].first>=l&&res[i].second<=r){ sz++; } } } if(ans==0){ cout<<0<<endl; return 0; } cout<<ans<<" "<<l<<" "<<r<<" "<<sz<<endl; if(ans!=0){ for(i=1;i<=n;i++){ if(res[i].first>=l&&res[i].second<=r){ cout<<i<<" "; } } } cout<<endl; }