首页 > 技术文章 > P1083 借教室

pyyyyyy 2019-07-03 11:13 原文

蒟蒻刚学了线段树的最最最最最嘴醉罪咀基本的东西,看什么题都想用线段树

题目链接

P1083 借教室

思路

如果不会线段树请点这里

题目中说的是求第一个不满足的申请人

我们可以把借教室的操作看成线段树的区间修改,把要借的教室数量\(d\)看成修改的值的相反数,然后我们记录一下区间的最小值就行了,如果进行区间修改操作后,最小值已经小于0就可以输出了

代码

#prag\
ma GCC optimize("Ofast")//请忽略这里
#include<bits/stdc++.h>
using namespace std;
#define int long long int
inline int read() {
    char c = getchar();
    int x = 0, f = 1;
    while(c < '0' || c > '9') {
        if(c == '-') f = -1;
        c = getchar();
    }
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}
const int N=1000005;
int n,m,a[N];
int minn[N*4],lazy[N*4];
void pushup(int root) {
	int lson=root<<1;
	int rson=root<<1|1;
	minn[root]=min(minn[lson],minn[rson]);
}
void build(int root,int l,int r) {//建树 
	int lson=root<<1;
	int rson=root<<1|1;
	if(l==r) {
		minn[root]=a[l];
		return ;
	}
	int mid=(l+r)/2;
	build(lson,l,mid);
	build(rson,mid+1,r);
	pushup(root);
}
void pushdown(int root) {//下放懒标记 
	int lson=root<<1;
	int rson=root<<1|1;
	if(lazy[root]) {
		minn[lson]+=lazy[root];
		minn[rson]+=lazy[root];
		lazy[lson]+=lazy[root];
		lazy[rson]+=lazy[root];
		lazy[root]=0;//懒标记一定要清空啊! 
	}
}
void update(int root,int l,int r,int x,int y,int v) {
	int lson=root<<1;
	int rson=root<<1|1;
	if(x<=l&&r<=y) {
		minn[root]+=v;
		lazy[root]+=v;
		return ;
	}
	int mid=(l+r)>>1;
	pushdown(root);
	if(x<=mid) update(lson,l,mid,x,y,v);
	if(y>mid) update(rson,mid+1,r,x,y,v);
	pushup(root);
}
signed main() {
	n=read();
	m=read();
	for(int i=1; i<=n; ++i) a[i]=read();
	build(1,1,n);
	for(int i=1; i<=m; ++i) {
		int d,s,t;
		cin>>d>>s>>t;
		update(1,1,n,s,t,-d);
		if(minn[1]<0) {//不能满足请求 
			printf("-1\n%d",i);
			return 0;
		}
	}
	cout<<0;
	return 0;
}

推荐阅读