借教室
来源:互联网 发布:微信一键群发软件免费 编辑:程序博客网 时间:2024/04/29 02:34
线段树+lazy
题目介绍:
在大学期间,经常需要租借教室。大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室。
教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样。面对海量租借教室的信息,我们自然希望编程解决这个问题。
我们假定,租借者对教室的大小、地点没有要求。即对于每份订单,我们只需要每天提供dj个教室,而它们具体是哪些教室,每天是否是相同的教室则不用考虑。借教室的原则是先到先得,也就是说我们要按照订单的先后顺序依次为每份订单分配教室。
如果在分配的过程中遇到一份订单无法完全满足,则需要停止教室的分配,通知当前申请人修改订单。这里的无法满足指从第sj天到第tj天中有至少一天剩余的教室数量不足dj个。现在我们需要知道,是否会有订单无法完全满足。如果有,需要通知哪一个申请人修改订单。
———————————分割—————————————-
输入:
输入文件为 classroom.in。第一行包含两个正整数n, m,表示天数和订单的数量。
第二行包含n个正整数,其中第i个数为ri,表示第i天可用于租借的教室数量。
接下来有m行,每行包含三个正整数dj, sj, tj ,表示租借的数量,租借开始、结束分别在第几天。每行相邻的两个数之间均用一个空格隔开。
天数与订单均用从1开始的整数编号。
输出:
输出文件为 classroom.out。
如果所有订单均可满足,则输出只有一行,包含一个整数 0。
否则(订单无法完全满足)输出两行,第一行输出一个负整数-1,第二行输出需要修改订单的申请人编号。
样例输入:
4 3 2 5 4 3 2 1 3 3 2 4 4 2 4
样例输出:
-1 2
数据范围:
对于 10%的数据,有1 ≤ n, m ≤ 10;
对于 30%的数据,有1 ≤ n, m ≤ 1000;
对于 70%的数据,有1 ≤ n, m ≤ 10^5;
对于 100%的数据,有1 ≤ n, m ≤ 10^6, 0 ≤ ri, dj≤ 10^9, 1 ≤ sj≤ tj≤ n。
—往下看
把题目抽空后:
给你一组数字,动态的对一段区间内的数减去一个值,只要这组数里出现了一个负数,就可以输出答案。
——-思路——-
动态的去除一段数,明显就是可以考虑线段树,树状数组一类的区间维护。
——-告诉你解法——-
解法一:二分+前缀和,可以稳过。(此方法我可没想,可以参考其他大牛。)
解法二:线段树+lazy,对于此题几乎可以过,但常数有些大,就有风险了。
——-解法二——-
用线段树维护这个区间,每次对一段区间进行操作时,打下lazy标记,对于每个询问只需要查询tree[1].min值就可以了。
以下为free pascal代码。
type cy=record value,labe:int64; end;const maxn=1000005;var a:array[0..maxn]of longint; tree:array[0..4*maxn]of cy; i,x,y,z,ans,n,m:longint;function min(x,y:longint):longint;begin if x<y then exit(x) else exit(y);end;procedure maketree(p,l,r:longint);var mid:longint;begin if l=r then begin tree[p].value:=a[l]; tree[p].labe:=0; exit; end; tree[p].labe:=0; mid:=(l+r)>>1; maketree(p*2,l,mid); maketree(p*2+1,mid+1,r); tree[p].value:=min(tree[p<<1].value,tree[p<<1+1].value); tree[p].labe:=0;end;procedure push(p:longint;x:int64);begin inc(tree[p<<1].labe,x); inc(tree[p<<1+1].labe,x); dec(tree[p<<1].value,x); dec(tree[p<<1+1].value,x);end;procedure change(p,l,r,a,b,take:longint);var mid:longint;begin if (l=a)and(r=b) then begin tree[p].value:=tree[p].value-take; tree[p].labe:=tree[p].labe+take; exit; end; push(p,tree[p].labe); tree[p].labe:=0; mid:=(l+r)>>1; if b<=mid then change(p*2,l,mid,a,b,take) else if a>mid then change(p*2+1,mid+1,r,a,b,take) else begin change(p*2,l,mid,a,mid,take); change(p*2+1,mid+1,r,mid+1,b,take); end; tree[p].value:=min(tree[p<<1].value,tree[p<<1+1].value);end;begin assign(input,'class.in'); reset(input); assign(output,'class.out'); rewrite(output); readln(n,m); for i:=1 to n do read(a[i]); maketree(1,1,n); for i:=1 to m do begin readln(z,x,y); change(1,1,n,x,y,z); ans:=tree[1].value; if ans<0 then begin writeln(-1); writeln(i); halt; end; end; writeln(0); close(input); close(output);end.
今天就这样了。
- 借教室
- 借教室
- 借教室
- 借教室
- 借教室
- Wikioi-1217-借教室
- COGS 1266 借教室
- vijos 1782 借教室
- vijos1782借教室
- noip2012 借教室
- 借教室续
- NOIP2012 借教室
- NOIP2012 借教室
- [NOIP 2012] 借教室
- NOIP2012 借教室
- NOIp2012 借教室
- NOIP 2012 借教室
- NOIP 2012 借教室
- bzoj1041 圆上的整点
- Udemy上Gephi教程笔记2
- Hessian 调用实例
- SQL join连接
- 《python计算机视觉编程》读书笔记------9(Scipy篇)
- 借教室
- 组合模式
- Spring MVC 小试牛刀
- movsb movsw movsd 指令详解
- 数据库中的查找语句
- Nginx反向代理配置
- Date和SimpleDateFormat类表示时间
- Centos下进行磁盘分区的配额功能
- MySQL批量SQL插入各种性能优化