我的思路是用线段树维护区间最小值,每个客户输入后先进行区间查询,如果区间最小值大于客户要求的教室数量就标记
#include <iostream>
#include <vector>
#define ls p<<1
#define rs p<<1|1
#define lsm tree[ls].min
#define rsm tree[rs].min
#define pm tree[p].min
using namespace std;
typedef struct Tree{
int l,r;
int min;
int lazy;
}Tree;
int n,m;
vector<int> a; //原数组
vector<Tree> tree; //线段树
void build(int l, int r, int p)
{
tree[p] = {l, r, INT32_MAX, 0};
if(l == r) pm = a[l];
else{
int m = l + r >> 1;
build(l, m, ls);
build(m+1, r, rs);
pm = min(lsm, rsm);
}
}
void pushdown(int p)
{
int k = tree[p].lazy;
if(k){
lsm -= k;
rsm -= k;
tree[ls].lazy += k;
tree[rs].lazy += k;
tree[p].lazy = 0;
}
}
void update(int l, int r, int k, int p)
{
if(tree[p].l>=l && tree[p].r<=r){
pm -= k;
tree[p].lazy += k;
}else{
pushdown(p);
int m = tree[p].r + tree[p].l >> 1;
if(m >= l) update(l,r,k,ls);
if(m < r) update(l,r,k,rs);
pm = min(lsm, rsm);
}
}
int Q(int l, int r, int p)
{
if(tree[p].l>=l && tree[p].r<=r)
return pm;
else{
pushdown(p);
int m = tree[p].r + tree[p].l >> 1;
int lm,rm;
if(m >= l) lm = Q(l,r,ls);
if(m < r) rm = Q(l,r,rs);
return min(lm, rm);
}
}
int main()
{
cin >> n >> m;
int flag = 1; //记录是否有需要修改的客户,1表示不需要修改
int res = 0;
a.resize(n+1);
tree.resize(n<<2);
for(int i=1; i<=n; i++) cin >> a[i];
build(1, n, 1);
while(m--){
int d,s,t;
cin >> d >> s >> t;
if(!flag) continue;
int q = Q(s,t,1);
if(q >= d){
res++;
update(s,t,d,1);
}
else{
flag = 0;
res++;
}
}
if(flag) cout << 0;
else{
cout << -1 << endl;
cout << res << endl;
}
return 0;
}