noip 2012 Day2 T2 借教室
一、暴力简述
首先我们不难看出,这道题————并不是一道多难的题,因为显然,第一眼看题目时便很容易地想到暴力如何打:枚举每一种订单,然后针对每一种订单,对区间内的每一天进行修改(做减法),直到某一份订单使得某一天剩下的教室数量为负数,即可得出结果。
先小小的评析一下吧:凡是能打出几近正解的暴力题,都不是难题!(蒟蒻可以骗到50+的不就是水题吗qwq)但是,显然枚举形式的暴力会很慢,期望的时间复杂度约为
O(m \times n)O(m×n),
可能会更快一些(但没卵用qwq)
二、思想详述
让我们开动脑筋想一下:每张订单其实就可以看作是一个区间(操作),左右区间分别为开始时间和结束时间,所以这不就是一个区间操作吗——首选线段tree啦!但是我在这里并不打算介绍线段树,因为虽然线段tree操作方便、复杂度低,但是——————我不会写啊qwq!(逃
并且总感觉你考试的时候撸一个线段树模板的时间完全可以多打两个暴力啊qwq(虽然暴力也不一定对)
所以,选择引入一种好理解、好实现的算法:差分数组
在介绍差分之前,需要介绍前缀和思想
(qwq此处当然只会讲一维线性的前缀和啦)
我们有一组数(个数小于等于一千万),并且有一大堆询问——给定区间l、r,求l、r之间所有数之和(询问个数小于等于一千万)
此处暴力肯定不行啊(O(NQlength)),那么我们来观察前缀和是怎么做的:用sum[i]来存储前i个数的和,然后用sum[r]-sum[l-1]来表示l~r之间所有数的和。(l-1原因是l~r只看要包含l)而sum数组便可以通过简单的递推求出来
代码核心:
for(int i=;i<=n;i++)
{cin>>a[i];sum[i]=sum[i-]+a[i];}
for(int i=;i<=q;i++)
{cin>>l>>r;cout<<sum[r]-sum[l-]<<" ";}
而所谓的差分数组,即是前缀和数组的逆运算:
我们给定前i个数相邻两个数的差(1<=i<=n),求每一项a[i](1<=i<=n)。
此时无非就是用作差的方式求得每一项,此时我们可以有一个作差数组cnt,cnt[i]用于记录a[i]-a[i-1],然后对于每一项a[i],我们可以递推出来:
for(int i=;i<=n;i++)
{cin>>diff[i];a[i]=diff[i]+a[i-];}
for(int i=;i<=n;i++)
{cout<<a[i];}
到这儿,我们可以看出来,前缀和是用元数据求元与元之间的并集关系,而差分则是根据元与元之间的逻辑关系求元数据,是互逆思想(qwq但是有时元数据和关系数据不是很好辨别或者产生角色反演啊)
但是,理解了前缀和&差分,并不代表肯定能做到模板题:毕竟,思想只能是辅助工具啊
三、关于答案二分
一般来说,二分是个很有用的优化途径,因为这样会直接导致减半运算,而对于能否二分,有一个界定标准:状态的决策过程或者序列是否满足单调性或者可以局部舍弃性。 而在这个题里,因为如果前一份订单都不满足,那么之后的所有订单都不用继续考虑;而如果后一份订单都满足,那么之前的所有订单一定都可以满足,符合局部舍弃性,所以可以二分订单数量。
四、终于要bb正解了!
首先,要明白如为什么要用区间差分而不是区间前缀和:因为这个题每次操作针对的对象都是原本题目中给的元数据,而不是让求某个关系,所以采用差分。
其次,要知道差分会起到怎样的作用:因为diff数组决定着每个元数据的变化大小、趋势,所以,当我们想要针对区间操作时,钱可以转化成对diff数组操作:
cnt[l[i]]+=d[i];
cnt[r[i]+1]-=d[i];//d[i]是指每天要借的教室数
因为后面的元数据都由之前的diff数组推导出来,所以改变diff[i]就相当于改变i之后的每一个值,并通过重新减去改变的量,达到操作区间的目的。
then,我们需要想明白策略:从第一份订单开始枚举,直到无法满足或者全枚举完结束。
最后,一点提示,我下面的标程是通过比大小来判断是否满足,而不是作差判负数————能不出负数就别出负数,否则容易基佬紫(re)/手动滑稽
贴标程:
#include <bits/stdc++.h> using namespace std; #define INF 0x3f3f3f3f
#define MAXN 1000100
#define MAXM 5010 inline int read()
{
int x = ,ff = ;char ch = getchar();
while(!isdigit(ch))
{
if(ch == '-') ff = -;
ch = getchar();
}
while(isdigit(ch))
{
x = (x << ) + (x << ) + (ch ^ );
ch = getchar();
}
return x * ff;
} int a,b,tot = ,day[MAXN],d[MAXN],s[MAXN],t[MAXN],ans[MAXN],cnt[MAXN];
bool pd(int x)
{
memset(cnt,,sizeof(cnt));
for(int i = ;i <= x;++i)
{
cnt[s[i]] += d[i];
cnt[t[i] + ] -= d[i];
}
for(int i = ;i <= a;++i)
{
ans[i] = ans[i - ] + cnt[i];
if(ans[i] > day[i]) return false;
}
return true;
} int main()
{
a = read(); b = read();
for(int i = ;i <= a;++i)
day[i] = read();
for(int i = ;i <= b;++i)
{
d[i] = read();
s[i] = read();
t[i] = read();
}
if(pd(b)) {printf("");return ;}
int l = ,r = b;
while(l < r)
{
int mid = (l + r) >> ;
if(pd(mid)) l = mid + ;
else r = mid;
}
printf("-1\n%d\n",l);
system("PAUSE");
return ;
}
noip 2012 Day2 T2 借教室的更多相关文章
- NOIP2012 DAY2 T2借教室
题目描述 在大学期间,经常需要租借教室.大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室.教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样. 面对海量租借教室的信息,我们自然 ...
- NOIP2012提高组day2 T2借教室
这题骗分可以骗到满分(可能是数据不太强给强行过去了) 这道题如果是按照题意去模拟用循环去修改区间的话只有45分,正解是二分+差分数组,骗分也是差分数组但是没有使用二分,时间复杂度在最坏的情况下是O(n ...
- NOIP2012 D2 T2借教室
先上题目 题目描述 在大学期间,经常需要租借教室.大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室.教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样. 面对海量租借教室的信息 ...
- NOIP 2012 Day2
tags: 扩展欧几里得 二分答案 查分 倍增 二分答案 贪心 NOIP categories: 信息学竞赛 总结 同余方程 借教室 疫情控制 同余方程 Solution 首先同余式可以转化为等式. ...
- NOIP2012 D2 T2 借教室 线段树 OR 二分法
题目描述: 在大学期间,经常需要租借教室.大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室.教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样. 面对海量租借教室的信息,我们自 ...
- LUGOU 3959 宝藏 (noip 2017 day2 T2)
传送门 解题思路 去年noip现在拿来写..思路还是听清楚的,记忆化搜索,f[S]表示现在选了集合S时的最小代价,dis[i]表示达到最优时i这个点的深度.f[S| (1< < i-1) ...
- Codevs 1217 借教室 2012年NOIP全国联赛提高组
1217 借教室 2012年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 在大学期间,经常需要租借教 ...
- NOIp 2012 #2 借教室 Label:区间修改线段树
题目描述 在大学期间,经常需要租借教室.大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室.教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样. 面对海量租借教室的信息,我们自然 ...
- NOIP 2012 Day2T2 借教室题解
NOIP 2012 Day2T2 借教室题解 题目传送门:http://codevs.cn/problem/1217/ 题目描述 Description 在大学期间,经常需要租借教室.大到院系举办活动 ...
随机推荐
- [ACM] POJ 3253 Fence Repair (Huffman树思想,优先队列)
Fence Repair Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 25274 Accepted: 8131 Des ...
- 新生入学V3.0颗粒归仓
新生入学系统V3.0接近尾声.每次做项目都有不一样的收获.V1.0,V2.0主要是熟悉了整个项目流程是怎样进行的,可行性分析--需求分析(原型图Axure)--实体设计(PD)--类图时序图(EA)- ...
- PHP生成excel(1)
先到PHPExcel官网下载PHPExcel类 http://phpexcel.codeplex.com/ 把excel类包含进来,然后直接使用 <?php require "./PH ...
- ActiveMQ(五) 转
package pfs.y2017.m11.mq.activemq.demo05; import javax.jms.Connection; import javax.jms.ConnectionFa ...
- [转载]C函数的实现(strcpy,atoi,atof,itoa,reverse)
在笔试面试中经常会遇到让你实现C语言中的一些函数比如strcpy,atoi等 1. atoi 把字符串s转换成数字 int Atoi( char *s ) { , i = ; ; ; isspace( ...
- hadoop yarn namenode datanoe 启动异常问题解决 分析日志
cat logs/hadoop-root-datanode-hadoop1.log ********************************************************** ...
- IMP-00009 And IMP-00028
导出文件异常结束” 错误,google一下,发现可能有如下原因导致 1.imp的数据太大,没有写buffer和commit 2.两个数据库字符集不同 3.从低版本exp的dmp文件,向高版本imp 4 ...
- org.eclipse.swt.SWTError: No more handles的解决办法
今天装了JBoss Tools 3.1 插件后,eclipse 打开jsp文件老是报错,或者要我关闭: org.eclipse.swt.SWTError: No more handles 网上找了两个 ...
- redis13-----配置文件
==配置文件全解=== ==基本配置 daemonize no 是否以后台进程启动 databases 创建database的数量(默认选中的是database ) #刷新快照到硬盘中,必须满足两者要 ...
- FileReader、 FileWriter、readLine()和newLine()、LineNumberReader(二十一)
1.字符流FileReader * 1.字符流是什么 * 字符流是可以直接读写字符的IO流 * 字符流读取字符, 就要先读取到字节数据, 然后转为字符. 如果要写出字符, 需要把字符转为字节再写出. ...