题目大意
给您 Q Q Q 个查询,请按顺序处理。
有以下三种类型:
1
:准备一个空花盆,在里面放一株植物。这里,植物的高度是 0 0 0 。2 T
:等待 T T T 天。在此期间,现有植物的高度会增加 T T T 。3 H
:收获所有高度至少达到 H H H 的植株,并输出收获植株的数量。收获的植物会从花盆中移出。
假设执行第一类和第三类查询所需的时间为零。
题目分析
根据数据范围分析可以得出暴力的时间复杂度是 O ( n 2 ) O(n^2) O(n2) ,显然会超时。
其中有一个难题是如何给数组中每一个数都加上 T T T 呢?我们知道一个定理:给一个不等式两边同时加上或减去同一个数不等式依然成立。那么我们就可以把每一个数都加上 T T T 的操作等价于把之后每个查询的 H H H 变成 H H H- T T T 即可。
但是还有一个问题,如何判断是否高度至少达到 H H H 呢?我们可以先建立一个变量 S S S 来记录当前过去的天数。再把这个当前的 S S S 作为新建盆栽对应数组的值。然后查询数组的每个值是否小于 S − H S-H S−H 即可。
还可不可以再优化呢?我们可以联想一下[NOIP2016 普及组] 海港
这道题目的解法,建一个队列,只要对以后没有用的数据就直接弹出即可。
#include<bits/stdc++.h>
//记得开long long
#define int long long
using namespace std;
queue<int> q;
int t,s;
main(){
cin>>t;
while(t--){
int op,t,h;
cin>>op;
if(op==1){
//当前的s作为新建盆栽对应的值
q.push(s);
}
if(op==2){
cin>>t;
//把s加上过去的天数
s+=t;
}
if(op==3){
int js=0;
cin>>h;
//不断弹出不符合的数据
while(q.empty()==0&&q.front()<=s-h){
js++;
q.pop();
}
cout<<js<<endl;
}
}
return 0;
}