1. 程式人生 > >[BZOJ] 2276: [Poi2011]Temperature

[BZOJ] 2276: [Poi2011]Temperature

clu pan rep access int com tun sub out

2276: [Poi2011]Temperature

Time Limit: 20 Sec Memory Limit: 32 MB
Submit: 731 Solved: 334
[Submit][Status][Discuss]

Description

The Byteotian Institute of Meteorology (BIM) measures the air temperature daily. The measurement is done automatically, and its result immediately printed. Unfortunately, the ink in the printer has long dried out... The employees of BIM however realised the fact only recently, when the Byteotian Organisation for Meteorology (BOM) requested access to that data.

An eager intern by the name of Byteasar saved the day, as he systematically noted down the temperatures reported by two domestic alcohol thermometers placed on the north and south outside wall of the BIM building. It was established decades ago by various BIM employees that the temperature reported by the thermometer on the south wall of the building is never lower than the actual temperature, while that reported by the thermometer on the north wall of the building is never higher than the actual temperature. Thus even though the exact temperatures for each day remain somewhat of a mystery, the range they were in is known at least.

Fortunately for everyone involved (except Byteasar and you, perhaps), BOM does not require exact temperatures. They only want to know the longest period in which the temperature was not dropping (i.e. on each successive day it was no smaller than on the day before). In fact, the veteran head of BIM knows very well that BOM would like this period as long as possible. To whitewash the negligence he insists that Byteasar determines, based on his valuable notes, the longest period in which the temperature could have been

not dropping. Now this is a task that Byteasar did not quite expect on his BIM internship, and he honestly has no idea how to tackle it. He asks you for help in writing a program that determines the longest such period.

某國進行了連續n天的溫度測量,測量存在誤差,測量結果是第i天溫度在[l_i,r_i]範圍內。
求最長的連續的一段,滿足該段內可能溫度不降。

Input

In the first line of the standard input there is one integer n(1<=N<=1000000) that denotes the number of days for which Byteasar took notes on the temperature. The measurements from day are given in the line no.i+1 Each of those lines holds two integers, x and y (-10^9<=x<=y<=10^9). 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 degrees (Celsius, in case you wonder!) and never exceeds 50 degrees (-50<=x<=y<=50)

第一行n
下面n行,每行l_i,r_i
1<=n<=1000000

Output

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.

一行,表示該段的長度

Sample Input

6

6 10

1 5

4 8

2 5

6 8

3 5

Sample Output

4

HINT

Source

Analysis

一道思考題

顯然這道題有點SRM的熟悉的感覺(以前做過?)

不過記憶不是很清晰不是很敢確定(而且我那時沒有記比賽的習慣)

那麽首先畫個像溫度計一樣的圖

技術分享

有點像Flappy Bird

如果把上下界分離的話,令人聯想到USACO 銀組的亂發節

(因為如果這一天之後的溫度下界沒有這一天的高的話,答案是沒有影響的)

= =

解法單調隊列

維護隊列內的每一天的溫度下界單調遞減

因為對於待進隊元素 i ,如果他的溫度下界 ≥ 隊首元素的溫度下界的話, i 就顯然可以繼承隊首元素的答案,那麽他的答案就是隊首元素 +1

這樣隊列的溫度下界會成一個遞減狀

但是進隊元素的下界不一定僅僅是高於隊首元素,也有可能高於隊首至隊列中間的一大段元素

所以 i 可以繼承的應該是最後一個矮於它的元素的答案

那麽 ans[ i ] = ans[ que[head] ] + i - que[ head ] -1

然後一個while解決問題

為什麽有個-1被標成了紅色:我個人覺得那個-1是不需要加的,但是在後期的Debug中發現不加不行

= =還是太弱啊

那麽到後面結束遍歷後,需要再處理一下隊內

這個時候隊內的元素都是可以直接持續到第 n 天的,直接處理就好

至於這個解法的更多問題,都可以用單調隊列的性質解決

Code

技術分享
 1 #include<cstdio>
 2 #include<iostream>
 3 #define maxn 1000100
 4 using namespace std;
 5 
 6 int n,minh[maxn],maxh[maxn],ans[maxn];
 7 int que[maxn],head,tail;
 8 
 9 int main(){
10     scanf("%d",&n);
11     
12     for(int i = 1;i <= n;i++){
13         scanf("%d%d",&minh[i],&maxh[i]);
14         ans[i] = 1;
15     }
16     
17     for(int i = 1;i <= n;i++){
18         while(tail < head && minh[que[tail+1]] > maxh[i])
19             ans[que[tail+1]] += i-que[tail+1]-1,
20             tail++;
21         while(tail < head && minh[que[head]] <= minh[i])
22             ans[i] = ans[que[head]]+i-que[head],
23             head--;
24         que[++head] = i;
25         
26 //        for(int i = tail+1;i <= head;i++)
27 //            printf("%d ",que[i]);cout << endl;
28 //        for(int i = 1;i <= n;i++)
29 //            printf("%d ",ans[i]);cout << endl;
30 //        
31     }
32     
33     while(tail < head)
34         ans[que[tail+1]] += n-que[tail+1],
35         tail++;
36     
37 //    for(int i = 1;i <= n;i++){
38 //        printf("%d ",ans[i]);
39 //    }
40 //    
41     int ret = 1;
42     for(int i = 1;i <= n;i++)
43         ret = max(ret,ans[i]);
44     printf("%d",ret);
45     
46     return 0;
47 }
心情極差qwq

[BZOJ] 2276: [Poi2011]Temperature