题目链接:https://vijos.org/p/1782
题意:一个区间1,n。m次操作,每次操作让l,r区间值减去d,当有任何一个值小于0就输出当前是第几个操作 这道题其实是没有什么难度的,是线段树中比较常规的题,我写它主要是为了更好的理解lazy标记,之前老师讲线段树我没听懂,所以都只有自己慢慢搞♂了,lazy标记就是与操作挂钩的一个值,根据题的意思不同lazy标记存的东西也会不同,针对这道题来说,lazy标记就是处理当前区间要减去多少天,如果lazy标记不为0说明目前这个区间的值还没有处理,是不正确的值,当lazy=0才表明当前区间的答案是正确的。
这道题我还是wa了很多次的,最后我把范围开大了才过了,当然我这个地方就有点不懂了,题目说的是10^6次方,所以线段树区间我就是(10^6+5)*4但是还是WA了两组,后来把这个区间开大了才AC,不知道原因是啥,如果有大佬知道还望指点一下
代码如下:
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<cstdlib> 6 #include<cmath> 7 #include<queue> 8 #define lson pos<<1 9 #define rson pos<<1|1 10 #define maxn 10000005//???? 11 using namespace std; 12 13 int n,m,minn[maxn<<2],lazy[maxn<<2],a[maxn]; 14 15 void pushup(int pos) 16 { 17 minn[pos]=min(minn[lson],minn[rson]); 18 } 19 20 void build(int l,int r,int pos) 21 { 22 if(l==r){ 23 minn[pos]=a[l];return; 24 } 25 if(l>r)return; 26 int mid=(l+r)>>1; 27 build(l,mid,lson); 28 build(mid+1,r,rson); 29 pushup(pos); 30 } 31 32 void pushdown(int pos) 33 { 34 minn[pos]-=lazy[pos]; 35 lazy[lson]+=lazy[pos]; 36 lazy[rson]+=lazy[pos]; 37 lazy[pos]=0; 38 } 39 40 void modify(int l,int r,int pos,int al,int ar,int x) 41 { 42 if(lazy[pos])pushdown(pos);//如果pos区间还没有处理 43 if(al<=l&&r<=ar){ 44 lazy[pos]=x; 45 pushdown(pos); 46 return; 47 } 48 if(al>r||ar<l)return; 49 int mid=(l+r)>>1; 50 modify(l,mid,lson,al,ar,x); 51 modify(mid+1,r,rson,al,ar,x); 52 pushup(pos); 53 } 54 55 int main() 56 { 57 freopen("fuck.txt","r",stdin); 58 scanf("%d%d",&n,&m); 59 for(int i=1;i<=n;i++) 60 { 61 scanf("%d",&a[i]); 62 } 63 build(1,n,1); 64 int d,x,y; 65 for(int i=1;i<=m;i++) 66 { 67 scanf("%d%d%d",&d,&x,&y); 68 modify(1,n,1,x,y,d); 69 if(minn[1]<0){ 70 printf("-1 %d",i); 71 return 0; 72 } 73 } 74 printf("0"); 75 }