什么? 要用差分, 二分???不要欺负蒟蒻啊 QWQQWQ

那就先想一想暴力吧

显然对每个需求,暴力修改,如果超出供给直接输出,得了 4545 分, 如下

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<cmath>
#define LL long long
#define rep(i, a, b) for(int i = a; i <= b; ++i)
#define per(i, a, b) for(int i = a; i >= b; --i)
#define clr(a,b)  memset((a),b,sizeof(a))
using namespace std;
inline int Read(){
    int s = 0, w = 1; char ch = getchar();
    while(ch < '0' || ch > '9')   { if(ch == '-') w = -1; ch = getchar(); }
    while(ch >= '0' && ch <= '9') { s = (s << 3) + (s << 1) + (ch ^ 48); ch = getchar(); }
    return s * w;
}
const int MX = 5e5 + 50;
int d[MX], t[MX], r[MX], s[MX], N, M, u[MX];
void solve() {
    rep(i, 1, N) {
        rep(j, s[i], t[i]) {
            u[j] += d[i];
            if(u[j] > r[j]) {
                printf("-1\n%d\n", i);
                exit(0);
            }
        }
    }
    puts("0");
}
int main() {
    N = Read(), M = Read();
    rep(i, 1, N) r[i] = Read();
    rep(i, 1, M) d[i] = Read(), s[i] = Read(), t[i] = Read();
    solve();
    return 0;
}

挠头 ing ~ -1s...~-1s....ing 1s... 1s....

啊!

线段树!!!

既然要区间修改,线段树啊!!

我们发现此题只需用线段树维护一下最小值即可,如果区间修改的时候最小值减去当前的需求已经为负,直接输出即可 OvOOvO

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<cmath>
#define LL long long
#define rep(i, a, b) for(int i = a; i <= b; ++i)
#define per(i, a, b) for(int i = a; i >= b; --i)
#define clr(a,b)  memset((a),b,sizeof(a))
using namespace std;
inline LL Read(){
    LL s = 0, w = 1; char ch = getchar();
    while(ch < '0' || ch > '9')   { if(ch == '-') w = -1; ch = getchar(); }
    while(ch >= '0' && ch <= '9') { s = (s << 3) + (s << 1) + (ch ^ 48); ch = getchar(); }
    return s * w;
}
const int MX = 2000010;
int t[MX], s[MX], N, M;
LL R[MX],tree[MX * 5], num, flag[MX * 5], d[MX];
void pushup(int now) { tree[now] = min(tree[now << 1], tree[now << 1 | 1]); } 
void Build_tree(int l, int r, int now) {
    if(l == r) {
        tree[now] = R[l];
        return;
    }
    int mid = (l + r) >> 1;
    Build_tree(l, mid, now << 1);
    Build_tree(mid + 1, r, now << 1 | 1);
    pushup(now);
}
void pushdown(int now) {
    if(flag[now]) {
        tree[now << 1] -= flag[now];
        tree[now << 1 | 1] -= flag[now];
        flag[now << 1] += flag[now];
        flag[now << 1 | 1] += flag[now];
        flag[now] = 0;
    }
    return;
}
void updata(int l, int r, int now, int x, int y, LL z) {
    if(x <= l && r <= y) {
        if(tree[now] - z < 0) {
            printf("-1\n%lld\n", num);
            exit(0);
        }
        tree[now] -= z;
        flag[now] += z;
        return;
    }
    int mid = (l + r) >> 1;
    pushdown(now);
    if(x <= mid) updata(l, mid, now << 1, x, y, z);
    if(y > mid) updata(mid + 1, r, now << 1 | 1, x, y, z);
    pushup(now);
}
void solve() {
    for(num = 1; num <= M; ++num) updata(1, N, 1, s[num], t[num], d[num]);
    cout << "0" << endl;
}
int main() {
    N = Read(), M = Read();
    rep(i, 1, N) R[i] = Read();
    rep(i, 1, M) d[i] = Read(), s[i] = Read(), t[i] = Read();
    Build_tree(1, N, 1);
    solve();
    return 0;
}

ByBy 飞马の幻想

End~End