P3522 [POI2011]TEM-Temperature(单调队列)
Posted li_wen_zhuo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3522 [POI2011]TEM-Temperature(单调队列)相关的知识,希望对你有一定的参考价值。
题目描述
某国进行了连续 n( 1≤n≤1,000,000)天的温度测量,测量存在误差,测量结果是第 ii 天温度在 [li,ri] 范围内。
求最长的连续的一段,满足该段内可能温度不降。
输入格式
In the first line of the standard input there is one integer n n ( 1 \\le n \\le 1,000,000 1≤n≤1,000,000) that denotes the number of days for which Byteasar took notes on the temperature. The measurements from day are given in the {(i + 1)}(i+1)-th line . Each of those lines holds two integers, x x and y y ( −109≤x≤y≤109 ). These denote, respectively, the minimum and maximum possible temperature on that particular day, as reported by the two thermometers.
In some of the tests, worth 50 points in total, the temperatures never drop below -50 −50 degrees (Celsius, in case you wonder!) and never exceeds 50 50 degrees ( −50≤x≤y≤50).
输出格式
In the first and only line of the standard output your program should print a single integer, namely the maximum number of days for which the temperature in Byteotia could have been not dropping.
输入输出样例
输入
6
6 10
1 5
4 8
2 5
6 8
3 5
输出
4
题目分析
通过分析题目我们可以发现:只有这一段序列每天的最高温度大于这一天以前每天的最低温度,才能满足序列不下降。
只要发现了这一点,后面就好办了。
我们可以用单调队列维护一段序列中l[i]的最大值,每次放入i时,先将序列中温度最小值大于 r[i] 的点弹出。
于是以i为结尾的最大合法解即为:i-l[q[head]-1] //q[head-1]到q[i]之间的非极值的点也是可以放入序列中作为合法解的一部分的。
代码如下
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <set>
#include <map>
#include <queue>
#include <vector>
#include <algorithm>
#include <iomanip>
#define LL long long
#define ULL unsigned long long
#define PII pair<int,int>
#define PLL pair<LL,LL>
#define PDD pair<double,double>
#define x first
#define y second
using namespace std;
const int N=1e6+5,INF=1e9;
int l[N],r[N],q[N];
int main()
{
cin.tie(0);
ios::sync_with_stdio(false);
int n;
cin>>n;
for(int i=1;i<=n;i++) cin>>l[i]>>r[i];
int ans=1; //答案的最小值就是1
int head=0,tail=-1;
for(int i=1;i<=n;i++)
{
while(head<=tail&&l[q[head]]>r[i]) head++; //将序列中温度最小值大于 r[i] 的点弹出
if(head<=tail) ans=max(ans,i-q[head-1]); //记录以i为结尾的最长合法序列
while(head<=tail&&l[q[tail]]<l[i]) tail--; //将l[i]放入单调队列中
q[++tail]=i;
}
cout<<ans<<endl;
return 0;
}
以上是关于P3522 [POI2011]TEM-Temperature(单调队列)的主要内容,如果未能解决你的问题,请参考以下文章