【wikioi】1217 借教室
题目链接http://www.wikioi.com/problem/1217/
算法:二分答案(线段树可过wikioi数据)
- 二分:http://www.wikioi.com/solution/list/1217/ (我不多阐述)
不难看出这道题满足二分条件 所以我们对数据进行二分
维护一个具有前缀和性质的数组sum记录当前二分区间内的教室需求情况,那么第i天需要的教室数为∑sum(1→i)。
维护方法:若订单i是从si天到ti天要借di个教室,那么sum[si]+=di,sum[ti+1]-=di。
计算每天的需求量是否超出教室量,如果有,答案必定在该区间,继续二分该区间,否则答案应该在另一个区间,继续二分。
(如果答案是0,一直二分下去肯定会有l = r的情况,然后就跳出来了=-=,此时m = l - 1)
丧心病狂の加速:如果不是二分区间内的而且没读入的数据,你读它什么呢?233
(这样写的好处有:①比线段树代码短②比线段树速度快 >_<)
我的代码
#include <cstdio>
using namespace std; #define MID (l+r) >> 1 const int maxn = 1000000+10;
int sum[maxn], cl[maxn], d[maxn], s[maxn], t[maxn], n, m, last, last_q; int check(int r) {
int ret = 0;
for(int i = 1; i <= n; ++i) { //这里必须要到n,因为是用前缀和, 即sum[t[i]]的t[i]后可能还有sum= =。。
ret += sum[i];
if(ret > cl[i]) return 0;
}
return 1;
} int main() {
scanf("%d%d", &n, &m);
int l = 1, r = m, mid, i;
for(i = 1; i <= n; ++i) scanf("%d", &cl[i]);
while(l <= r) {
mid = MID;
if(last_q < mid){
for(i = last+1; i <= mid; ++i) scanf("%d%d%d", &d[i], &s[i], &t[i]);
last_q = mid;
}
//这里最容易错,要清楚标记
for(i = mid+1; i <= last; ++i) sum[s[i]] -= d[i], sum[t[i]+1] += d[i]; //将原来加上去的和减的恢复
for(i = last+1; i <= mid; ++i) sum[s[i]] += d[i], sum[t[i]+1] -= d[i]; //加上去的和减去新添加的元素
last = mid;
if(check(mid)) l = mid+1;
else r = mid-1;
}
//一般闭区间二分的答案是l-1,在这里,l-1=m时说明所有人都满足
if(l-1 == m) printf("0");
else printf("-1\n%d", l); //而因为l-1是答案,所以l-1+1=l就是下一个不符合答案的
return 0;
} - 线段树(区间更新和维护最小)
注意:用线段树最容易错的地方就是认为当修改后全部教室加起来的和为负的那个人就是解。其实应该是每天的教室需求量,不是和。所以不能维护区间和,要维护一个最小值,最小值为负,说明这个人就是答案
#include <cstdio>
using namespace std; #define lson l, m, rt << 1
#define rson m+1, r, rt << 1 | 1
#define MID (l+r)>>1
#define lc rt << 1
#define rc rt << 1 | 1 int min(const int& a, const int& b){return a < b ? a : b;} const int maxn = 1e6+10;
int minx[maxn << 2], add[maxn << 2], n, m, L, R, _add; //向上传递最小的
void pushup(int rt) {
minx[rt] = min(minx[lc], minx[rc]);
} //向下传递修改值
void pushdown(int rt) {
if(add[rt]) {
add[lc] += add[rt];
add[rc] += add[rt];
minx[lc] += add[rt];
minx[rc] += add[rt];
add[rt] = 0;
}
} void build(int l, int r, int rt) {
add[rt] = 0;
if(l == r) {
scanf("%d", &minx[rt]);
return;
}
int m = MID;
build(lson); build(rson);
pushup(rt);
} void update(int l, int r, int rt) {
if(L <= l && r <= R) {
add[rt] += _add;
minx[rt] += _add; //这里直接修改即可
return;
}
pushdown(rt);
int m = MID;
if(L <= m) update(lson);
if(m < R) update(rson);
pushup(rt);
} int main() {
scanf("%d%d", &n, &m);
build(1, n, 1);
int i;
for(i = 1; i <= m; ++i) {
scanf("%d%d%d", &_add, &L, &R);
_add = -_add;
update(1, n, 1);
if(minx[1] < 0) { printf("-1\n%d", i); return 0;}
}
printf("0");
return 0;
}
【wikioi】1217 借教室的更多相关文章
- Codevs 1217 借教室 2012年NOIP全国联赛提高组
1217 借教室 2012年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 在大学期间,经常需要租借教 ...
- codevs 1217 借教室
传送门 1217 借教室 2012年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Descripti ...
- 借教室(codevs 1217)
1217 借教室 2012年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Descrip ...
- NOIP 2012 Day2T2 借教室题解
NOIP 2012 Day2T2 借教室题解 题目传送门:http://codevs.cn/problem/1217/ 题目描述 Description 在大学期间,经常需要租借教室.大到院系举办活动 ...
- NOIP2012借教室[线段树|离线 差分 二分答案]
题目描述 在大学期间,经常需要租借教室.大到院系举办活动,小到学习小组自习讨论,都需要 向学校申请借教室.教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样. 面对海量租借教室的信息,我们自 ...
- [NOIP2012] 提高组 洛谷P1083 借教室
题目描述 在大学期间,经常需要租借教室.大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室.教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样. 面对海量租借教室的信息,我们自然 ...
- NOIp 2012 #2 借教室 Label:区间修改线段树
题目描述 在大学期间,经常需要租借教室.大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室.教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样. 面对海量租借教室的信息,我们自然 ...
- 【NOIP2012】借教室
因为本校OJ+1s所以用线段树水过了,不去syz的水库水这题还真不知道线段树过不了= = 原题: 在大学期间,经常需要租借教室.大到院系举办活动,小到学习小组自习讨论,都需要 向学校申请借教室.教室的 ...
- NOIP 2012 T5 借教室 [洛谷P1083]
题目描述 在大学期间,经常需要租借教室.大到院系举办活动,小到学习小组自习讨论,都需要 向学校申请借教室.教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样. 面对海量租借教室的信息,我们自 ...
随机推荐
- vlan与交换机端口模式Access,Hybrid,Trunk
以太网端口有三种链路类型:Access.Hybrid和Trunk.Access类型的端口只能属于1个VLAN,一般用于连接计算机的端口:Trunk类型的端口可以允许多个VLAN通过,可以接收和发送多个 ...
- VC++ TinyXML
下载TinyXML库文件http://sourceforge.net/projects/tinyxml/ 在TinyXML的目录找到tinystr.h, tinyxml.h,tinystr.cpp,t ...
- web页面版权部分的显示问题
网站开发中绝大部分页面底部都需要版权信息,一般都是Copyright ©域名 2014 - 2015. All Rights Reserved.这种格式,当然也有其他的,有时候不太注意会发现做出的这个 ...
- codeforces A. K-Periodic Array 解题报告
题目链接:http://codeforces.com/problemset/problem/371/A 题目意思:给出n和k和一个只有1或者2组成的序列,需要求出最少的改变次数,使得 n/k 组里面的 ...
- FZU 2140 Forever 0.5 (几何构造)
Forever 0.5 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit ...
- [MAC] Mac下的SVN命令行
转载自: http://www.cnblogs.com/snandy/p/4072857.html Mac自带了SVN命令行,如我的升级到10.10(OSX yosemite)后命令行版本为1.7.1 ...
- Power Strings(poj 2406)
题意:求字符串中循环节出现的次数 KMP!!! #include<cstdio> #include<iostream> #include<cstring> #def ...
- win7下IIS配置MVC项目
第一步:添加MVC程序映射 1.双击打开,如下图: 2. 点击界面右边操作中的:添加脚本映射 请求路径:* 可执行文件路径:C:\Windows\Microsoft.NET\Framework\v4. ...
- c++ 继承 虚函数与多态性 重载 覆盖 隐藏
http://blog.csdn.net/lushujun2011/article/details/6827555 2011.9.27 1) 定义一个对象时,就调用了构造函数.如果一个类中没有定义任何 ...
- c++ static及const(开发者在线)
static 是c++中很常用的修饰符,它被用来控制变量的存储方式和可见性,下面我将从 static 修饰符的产生原因.作用谈起,全面分析static 修饰符的实质. static 的两大作用: 一. ...