一看就是暴力
好吧,其实是线段树或差分+二分,这里用的是差分+二分的做法。
二分部分的代码,套个二分板子就行
int left=1,right=m; while(left<right)//二分 { int mid=(left+right)>>1; if(check(mid)) left=mid+1; else right=mid; }
差分
bool check(int x)//差分,判断 { memset(f,0,sizeof(f)); for(int i=1;i<=x;i++) { f[l[i]]+=d[i]; f[r[i]+1]-=d[i]; } for(int i=1;i<=n;i++) { g[i]=g[i-1]+f[i]; if(a[i]<g[i]) return 0; } return 1; }
完整代码
#include<iostream> #include<stdio.h> #include<math.h> #include<string.h> #include<stdlib.h> #include<algorithm> using namespace std; const int maxn=1e6+5; int a[maxn],l[maxn],r[maxn],d[maxn],f[maxn],g[maxn],n,m; bool check(int x)//差分,判断 { memset(f,0,sizeof(f)); for(int i=1;i<=x;i++) { f[l[i]]+=d[i]; f[r[i]+1]-=d[i]; } for(int i=1;i<=n;i++) { g[i]=g[i-1]+f[i]; if(a[i]<g[i]) return 0; } return 1; } signed main() { ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); cin>>n>>m; for(int i=1;i<=n;i++) cin>>a[i]; for(int i=1;i<=m;i++) cin>>d[i]>>l[i]>>r[i]; if(check(n)) { cout<<"0"; return 0; } else cout<<"-1"<<endl; int left=1,right=m; while(left<right)//二分 { int mid=(left+right)>>1; if(check(mid)) left=mid+1; else right=mid; } cout<<left; return 0; }