正题
我们每加入一个区间,就将这个区间都加上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); }