【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]
题目描述 在大学期间,经常需要租借教室.大到院系举办活动,小到学习小组自习讨论,都需要 向学校申请借教室.教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样. 面对海量租借教室的信息,我们自 ...
随机推荐
- ImageMagick资料
ImageMagick资料 ---------------------------------------------------------------------------- ImageMagi ...
- 又一款linux提权辅助工具
又一款linux提权辅助工具 – Linux_Exploit_Suggester 2013-09-06 10:34 1455人阅读 评论(0) 收藏 举报 https://github.com/Pen ...
- JavaScript常用事件
一般事件 事件 浏览器支持 描述 onClick HTML: 2 | 3 | 3.2 | 4 Browser: IE3 | N2 | O3 鼠标点击事件,多用在某个对象控制的范围内的鼠标点击 on ...
- HDU 1087 Super Jumping! Jumping! Jumping! 最大递增子序列
Super Jumping! Jumping! Jumping! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 ...
- codeforces 486C. Palindrome Transformation 解题报告
题目链接:http://codeforces.com/problemset/problem/486/C 题目意思:给出一个含有 n 个小写字母的字符串 s 和指针初始化的位置(指向s的某个字符).可以 ...
- JS Replace 全部替换字符 用法
转载自:http://www.cnblogs.com/skykang/archive/2011/08/04/2127158.html <script language="javascr ...
- sublime 实用 快捷键
alt+- 向后导航 alt+shift+- 向前导航 ctrl+shift+↑↓ 上下移动一行 ctrl+k,ctrl+u 转换所选为大写 ctrl+k,ctrl+l(字母L) 转换所选为小写 ct ...
- JS输入框邮箱自动提示(带有demo和源码)(转载)
今天在javascriptQQ群里面 有童鞋问到 有没有 "JS输入框邮箱自动提示"插件,即说都找遍了github上源码 都没有看到这样类似的插件,然后我想了下 "JS输 ...
- jquery 展开折叠菜单
jquery 展开折叠菜单 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <ht ...
- wp8 入门到精通 LINQ to SQL
http://msdn.microsoft.com/zh-cn/library/bb397924.aspx LINQ 查询操作中的类型关系 (C#) 使用一个人类发明快速检索的方法 // Northw ...