[vijos1782]借教室<线段树>

时间:2023-03-09 17:59:22
[vijos1782]借教室<线段树>

题目链接: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,不知道原因是啥,如果有大佬知道还望指点一下

代码如下:

 #include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<queue>
#define lson pos<<1
#define rson pos<<1|1
#define maxn 10000005//????
using namespace std; int n,m,minn[maxn<<],lazy[maxn<<],a[maxn]; void pushup(int pos)
{
minn[pos]=min(minn[lson],minn[rson]);
} void build(int l,int r,int pos)
{
if(l==r){
minn[pos]=a[l];return;
}
if(l>r)return;
int mid=(l+r)>>;
build(l,mid,lson);
build(mid+,r,rson);
pushup(pos);
} void pushdown(int pos)
{
minn[pos]-=lazy[pos];
lazy[lson]+=lazy[pos];
lazy[rson]+=lazy[pos];
lazy[pos]=;
} void modify(int l,int r,int pos,int al,int ar,int x)
{
if(lazy[pos])pushdown(pos);//如果pos区间还没有处理
if(al<=l&&r<=ar){
lazy[pos]=x;
pushdown(pos);
return;
}
if(al>r||ar<l)return;
int mid=(l+r)>>;
modify(l,mid,lson,al,ar,x);
modify(mid+,r,rson,al,ar,x);
pushup(pos);
} int main()
{
freopen("fuck.txt","r",stdin);
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
}
build(,n,);
int d,x,y;
for(int i=;i<=m;i++)
{
scanf("%d%d%d",&d,&x,&y);
modify(,n,,x,y,d);
if(minn[]<){
printf("-1\n%d",i);
return ;
}
}
printf("");
}