TIOJ 1670 新聞採訪
Description
「我與小明不相見已有二年餘了,我最不能忘記的是他的雙腿。(雖然他根本沒有)」光陰荏苒,你如今是一位御用新聞記者,專門替國王烏龜的電視台採訪各式各樣的新聞。還記得TIOJ 1623--國王烏龜的接駁車嗎?大意就是國王烏龜開放死老百姓烏龜們去覲見國王,舉國上下無不歡聲雷動,一時之間各個直達皇宮接駁車的站牌前都排滿了烏龜,好不盛大!你自然被派遣過去負責採訪這場盛宴。並且他們看在你的才能,決定要讓你Live連線報導,你知道如果把這個難得的機會搞砸了你可能會變成小明第二。
因此,在開始報導之前你決定先去向前輩烏龜瞭解你的報導方式。
「
你待會要進行的報導方式呢,你看那邊有一條大排長龍的隊伍,共有 n 隻烏龜排成一列,你需要選擇一個區間 [A,B](包含A,B)進行採訪,採訪的方式是依序遞麥克風給這個區間每一隻烏龜,讓他們自由發言。必須注意的是因為要弄得看起來很有公信力,你採訪的總人數不能小於 L 個人。
當然自由發言是有危險成份在的,有些反國王份子可能會講出危言聳聽的話,危害國王聲譽,所以我們會依序把烏龜標號 0 或 1,0 表示危險份子、1 則是很安全。
所以,我們希望你能讓這個區間內 1 佔的比例越大越好,如果有很多個一樣好的區間,那就是總人數越少越好(但還是得 ≥L),如果還是有很多個,那就 A 越小越好。
你選好你要採訪的區間了嗎?告訴我吧。
」
Input Format
輸入第一行含一個正整數 T,表示接下來有幾條隊伍要採訪(幾組詢問)
每組詢問第一行含兩個正整數 n,L(L≤n),分別表示隊伍長度跟採訪總人數下限。
第二行會是一個長度為 n 的 01 序列,依序表現出每隻烏龜危不危險。
- T≤400
- 1≤n≤100,000
Output Format
對每組詢問輸出兩個正整數數字 A 和 B,表示 [A,B] 是你的最佳選擇。
※這個序列編號由 1 開始,到 n 為止。
Sample Input
2
17 5
00101011011011010
20 4
11100111100111110000
Sample Output
7 11
6 9
Solution
我們考慮更一般的情形:給定 a1,a2,…,an∈R 和 1≤k≤n,找出 [l,r]⊆[0,n] 在限制 r−l≥k 下最大化 f(l,r):=∑ri=l+1air−l 為了方便,對於每個 i≥k,定義- F(i):=max0≤j≤i−kf(j,i)。
- j∗(i) 為最大的 j 使得 f(j,i)=F(i)。
- G(i):=maxk≤i′≤iF(i′)。
![]() |
Pj∗(i) 必定在下凸包邊界 Ci−k 上,且藍色線段的斜率會在紅色和綠色線段的斜率之間。 |
回想一下,C0,…,Cn−k 能用 Andrew's 演算法在 O(n) 時間內依序做出來。只要對每個 i≥k,在 Ci−k 上做二分搜找出 j∗∗(i),就能在 O(nlogn) 時間解決這個問題。不幸的是,因為這題的 T 頗大,O(nlogn) 還是太慢。
以下介紹一個將時間複雜度降至 O(n) 的演算法。假定我們有一個指標 1≤p≤ci−k,滿足 m(Ci−k,p−1,Ci−k,p)≤G(i) 為了方便,如果 p=1,定義 m(Ci−k,p−1,Ci−k,p)=−∞。
首先,若 Ci−k,p∉Ci−k+1,則把 p 重設為ci−k+1−1。注意無論 p 是否被重設,我們都有 Ci−k+1,p−1=Ci−k,p−1 且 Ci−k+1,p=Ci−k,p,因此 m(Ci−k+1,p−1,Ci−k+1,p)=m(Ci−k,p−1,Ci−k,p)≤G(i).
![]() |
假定加入 Pi−k+1 後,Ci−k,p 被 pop 掉,則往左移動 p 至 Ci−k 與 Ci−k+1 最右邊的共同點 p′。注意紅色斜率 < 粉紅色斜率,且根據假設粉紅色斜率 ≤G(i),所以紅色斜率 ≤G(i)。 |
接著,在 Ci−k+1 上,往右移動 p 直到 p 碰到右邊界或 m(Ci−k+1,p,Ci−k+1,p+1)>m(Ci−k+1,p,Pi+1)。如果 j∗∗(i+1)≥p,這麼做會把 p 更新為 j∗∗(i+1),也能求出 F(i+1) 以及 j∗(i+1),且由 (1) 可得 m(Ci−k+1,p−1,Ci−k+1,p)≤F(i+1)≤G(i+1) 注意上式其實就是用 i=i+1 代入 (2) 的結果。
![]() |
如果 j∗∗(i+1)≥p,向右移動 p 至 p′ 後會得到 p′=j∗∗(i+1)。注意移動結束後藍色斜率 F(i+1)≥ 紅色斜率 m(Ci−k+1,p′−1,Ci−k+1,p′)。 |
如果 j∗∗(i+1)<p,這麼做並不會改變 p。由 (1),我們依然有 F(i+1)<m(Ci−k+1,p−1,Ci−k+1,p)≤G(i)=G(i+1) 在這種情況下我們沒辦法知道 F(i+1) 是多少,但因為 F(i+1)<G(i),F(i) 是多少其實根本不重要。
有了上述的討論,只要在 i=k 時設 p=1,接著從 i=k+1 做到 i=n,p 的總移動次數將是 O(n),因此時間複雜度也是 O(n)。
講起來似乎很複雜,其實 code 蠻簡單的:
https://ideone.com/ifDKHH
留言
張貼留言