#include<cstdio> #include<cstdlib> #include<algorithm> #include<cstring> using namespace std; int a[1000010]; int d[1000010]; int x[1000010]; int y[1000010]; int s[1000010],sum; int n,m,ans; bool cheak(int v) { memset(s,0,sizeof(s));sum=0; for(int i=1;i<=v;i++) { s[x[i]]+=d[i]; s[y[i]+1]-=d[i]; } for(int i=1;i<=n;i++) { sum+=s[i]; if(sum>a[i])return 0; } return 1; } int main() { 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%d",&d[i],&x[i],&y[i]); int l=1,r=m; while(l<=r) { int mid=(l+r)>>1; if(!cheak(mid)){ans=mid;r=mid-1;} else l=mid+1; } if(!ans)printf("0"); else printf("-1\n%d",ans); }
另一写法,线段树。
#include <cstdio> using namespace std; #define lson l, m, rt << 1 #define rson m+1, r, rt << 1 | 1 #define MID (l+r)>>1 #define lc rt << 1 #define rc rt << 1 | 1 int min(const int& a, const int& b){return a < b ? a : b;} const int maxn = 1e6+10; int minx[maxn << 2], add[maxn << 2], n, m, L, R, _add; //向上传递最小的 void pushup(int rt) { minx[rt] = min(minx[lc], minx[rc]); } //向下传递修改值 void pushdown(int rt) { if(add[rt]) { add[lc] += add[rt]; add[rc] += add[rt]; minx[lc] += add[rt]; minx[rc] += add[rt]; add[rt] = 0; } } void build(int l, int r, int rt) { add[rt] = 0; if(l == r) { scanf("%d", &minx[rt]); return; } int m = MID; build(lson); build(rson); pushup(rt); } void update(int l, int r, int rt) { if(L <= l && r <= R) { add[rt] += _add; minx[rt] += _add; //这里直接修改即可 return; } pushdown(rt); int m = MID; if(L <= m) update(lson); if(m < R) update(rson); pushup(rt); } int main() { scanf("%d%d", &n, &m); build(1, n, 1); int i; for(i = 1; i <= m; ++i) { scanf("%d%d%d", &_add, &L, &R); _add = -_add; update(1, n, 1); if(minx[1] < 0) { printf("-1\n%d", i); return 0;} } printf("0"); return 0; }