题目大意:某国进行了连续n天的温度测量,测量存在误差,测量结果是第i天温度在[l_i,r_i]范围内。
求最长的连续的一段,满足该段内可能温度不降。
第一行n
下面n行,每行l_i,r_i
1<=n<=1000000
一行,表示该段的长度
Sample Input
6
6 10
1 5
4 8
2 5
6 8
3 5
Sample Output
4
知识点:递推,单调队列
1 #include<bits/stdc++.h> 2 using namespace std; 3 queue<int> Q; 4 int l[1000005],r[1000005]; 5 int q[1000005]; 6 int N,t; 7 int MAX,ans,head,tail; 8 int main(){ 9 //freopen("temperature.in", "r", stdin); 10 //freopen("temperature.out", "w", stdout); 11 cin>>N; 12 for(int i=1;i<=N;i++) 13 scanf("%d%d",&l[i],&r[i]); 14 /* 15 单调队列分析: 16 1.什么情况下时间断裂:当你要加入的第i天,其r[i]<l[j](前几天中的l),这个时候, 17 要先更新答案,再从把第i天卡死的离第i天最近的一天重新计数 18 2.用一个不下降单调队列来操作,有一个关键:假设某一段时间的l值为 55 53 48 37 19 36 35 34 32 29 下面一天l值为45 则此队列更新为55 53 48 45。。。因为温度45 20 的天数靠后而且l值高,若这一天可以,则前六天一定可以,所以使队列元素为55 53 48 45. 21 但这样还不行,无法确定天数信息,所以让q[]保存天 22 数,利用l[q[head]]来调用,更新q就是更新l数组,反正是 23 O(n)地从前向后扫一遍,不影响答案 24 */ 25 head=1;tail=0; 26 for(int i=1;i<=N;i++){ 27 while(l[q[head]]>r[i]&&head<=tail) //q是单调减队列,如果当前的l[q[head]]>r[i] 28 head++ //则这一天不能从第q[head]天接上 因此继续向后 29 //找,直到l[q[head]]<r[i],由于是单调队列,所以 30 //后面几天一定可以 31 32 if(head<=tail)//更新ans 33 ans=max(ans,i-q[head]+1); 34 35 int t=i; 36 while(l[i]>l[q[tail]]&&head<=tail) 37 t=q[tail],tail--; 38 l[t]=l[i]; 39 q[++tail]=t; 40 } 41 cout<<ans; 42 return 0; 43 } 44
时间: 2024-10-08 17:16:46