线段树维护区间最小+带修区间-x
tag标记要子区间减去多少,实时更新。
push_down
inline void push_down(int rt){
mn[rt<<1]-=tag[rt];
mn[rt<<1|1]-=tag[rt];
tag[rt<<1]+=tag[rt];
tag[rt<<1|1]+=tag[rt];
tag[rt]=0;
update
void update(int p,int left,int right,int l,int r,int x){
if(l == left&&r == right){
mn[p]-=x;
tag[p] += x;
return;
}
if(tag[p])push_down(p);
int mid = (right+left)/2;
if(r <= mid){
update(p*2,left,mid,l,r,x);
}
else if(l > mid){
update(p*2+1,mid+1,right,l,r,x);
}
else{
update(p*2,left,mid,l,mid,x);
update(p*2+1,mid+1,right,mid+1,r,x);
}
push_up(p);
}
AC代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1000100;
struct sgt{
int mn[N*4];
int tag[N*4];
int a[N];
inline int _min(int a,int b){
return a>b?b:a;
}//手写min函数卡卡常
inline void push_up(int rt){
mn[rt]=_min(mn[rt<<1],mn[rt<<1|1]);
}
inline void push_down(int rt){
mn[rt<<1]-=tag[rt];
mn[rt<<1|1]-=tag[rt];
tag[rt<<1]+=tag[rt];
tag[rt<<1|1]+=tag[rt];
tag[rt]=0;
}
void build(int p,int l,int r){
if(l == r){
mn[p] = a[l];
return;
}
int mid = (l+r)/2;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
push_up(p);
}
void update(int p,int left,int right,int l,int r,int x){
if(l == left&&r == right){
mn[p]-=x;
tag[p] += x;
return;
}
if(tag[p])push_down(p);
int mid = (right+left)/2;
if(r <= mid){
update(p*2,left,mid,l,r,x);
}
else if(l > mid){
update(p*2+1,mid+1,right,l,r,x);
}
else{
update(p*2,left,mid,l,mid,x);
update(p*2+1,mid+1,right,mid+1,r,x);
}
push_up(p);
}
int query(int p,int left,int right,int l,int r){
if(l == left&&r == right){
push_down(p);
return mn[p];
}
int mid = (left+right)/2;
if(r <= mid){
return query(p*2,left,mid,l,r);
}
else if(l > mid){
return query(p*2+1,mid+1,right,l,r);
}
else{
return min(query(p*2,left,mid,l,mid),query(p*2+1,mid+1,right,mid+1,r));
}
}
}t;
int main(){
ios::sync_with_stdio(0);
int n,q;
cin>>n>>q;
for(int i = 1;i <= n;i++){
cin>>t.a[i];
}
t.build(1,1,n);
for(int i = 1;i <= q;i++){
int l,r,x;
cin>>x>>l>>r;
t.update(1,1,n,l,r,x);
if(t.mn[1] < 0){
cout<<-1<<endl;
cout<<i<<endl;
return 0;
}
}
cout<<0<<endl;
return 0;
}