正题
我们每加入一个区间,就将这个区间都加上dj,没错,我们只要看一下当前点的权值是否大于ri即可。
lazy优化+读入优化强行卡过
// luogu-judger-enable-o2
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std;
int n,m;
struct tree{
int ls,rs,x,y;
long long min,lazy;
}s[2000010];
int r[1000010];
int len=0;
/*inline char nc() {
static char buf[1000000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
}*/
inline int read(int &sum) {
char ch=getchar();
sum=0;
while(!(ch>='0'&&ch<='9'))
ch=getchar();
while(ch>='0'&&ch<='9')
sum=(sum<<3)+(sum<<1)+(ch^48),ch=getchar();
return sum;
}
void bt(int x,int y){
len++;
int i=len;
s[i].ls=s[i].rs=-1;
s[i].x=x;s[i].y=y;
s[i].min=0;s[i].lazy=0;
if(x==y) return ;
int mid=(x+y)/2;
s[i].ls=len+1;bt(x,mid);
s[i].rs=len+1;bt(mid+1,y);
}
void pushdown(int x){
int ls=s[x].ls,rs=s[x].rs;
if(s[ls].ls==-1 && s[ls].rs==-1) s[ls].min+=s[x].lazy;
else s[ls].lazy+=s[x].lazy,s[ls].min+=s[x].lazy;
if(s[rs].ls==-1 && s[rs].rs==-1) s[rs].min+=s[x].lazy;
else s[rs].lazy+=s[x].lazy,s[rs].min+=s[x].lazy;
s[x].lazy=0;
}
bool change(int p,int x,int y,int d){
if(s[p].ls==-1 && s[p].rs==-1){
s[p].min+=d;
return s[p].min>=0?true:false;
}
if(s[p].x==x && s[p].y==y){
s[p].lazy+=d;
s[p].min+=d;
return s[p].min>=0?true:false;
}
pushdown(p);
int mid=s[s[p].ls].y;
if(y<=mid) change(s[p].ls,x,y,d);
else if(x>mid) change(s[p].rs,x,y,d);
else change(s[p].ls,x,mid,d),change(s[p].rs,mid+1,y,d);
s[p].min=min(s[s[p].ls].min,s[s[p].rs].min);
return s[p].min>=0?true:false;
}
int main(){
read(n);
read(m);
bt(1,n);
for(int i=1;i<=n;i++){
int x;
read(x);
change(1,i,i,x);
}
for(int i=1;i<=m;i++){
int d,x,y;
read(d);
read(x);
read(y);
if(!change(1,x,y,-d)) {
printf("-1\n%d",i);
return 0;
}
}
printf("0");
}
另一种做法就是差分,这个做法很像树状数组该段求点。
有一个差分数组diff来表示当前这个与前一个值的差,那么我们要求其中的一个值,就直接算前缀和即可。
改段自然也就变得很简单,diff[i]+=d相当于原数组的i到n都加上d。
那如果我们要在x到y都加上d,那么直接在diff[x]+=d,diff[y+1]-=d即可。
#include<cstdio>
#include<cstdlib>
#include<cstring>
int chafen[1000010];
int r[1000010];
int n,m;
struct node{
int x,y,d;
}s[1000010];
bool check(int x){
memset(chafen,0,sizeof(chafen));
for(int i=1;i<=x;i++){
chafen[s[i].x]+=s[i].d;
chafen[s[i].y+1]-=s[i].d;
}
int tot=0;
for(int i=1;i<=n;i++){
tot+=chafen[i];
if(tot>r[i]) return false;
}
return true;
}
int main(){
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&r[i]);
for(int i=1;i<=m;i++) scanf("%d %d %d",&s[i].d,&s[i].x,&s[i].y);
int l=0,r=m;
int ans=0;
while(l<=r){
int mid=(l+r)/2;
if(check(mid)){
ans=mid+1;
l=mid+1;
}
else r=mid-1;
}
if(ans==m+1) printf("0");
else printf("-1\n%d",ans);
}