顯示具有 Topcoder SRM 標籤的文章。 顯示所有文章
顯示具有 Topcoder SRM 標籤的文章。 顯示所有文章

2015年3月25日 星期三

SRM654ˋ

向來在台灣時間早上的場次或許因為參加的人偏少,題目有偏間單的趨勢,這場也不例外,我難得沒有重大失誤的破台了。不過我每一題都 debug 好久就是了。

這場第一名Endagorion寫的 Editorial

250 --- SquareScores


題意:給一個由小寫字母和問號構成的字串,並且給你問號代表每個字母的機率,並定意一個字串的分數為所有字母都相同的 substring 個數 (不同位置算不同)。求這個字串的分數期望值。

數據範圍:字串長度($n$)不超過 $1000$。

tag:[ 數學 ] [ 期望值 ]

關鍵字:簡單期望值

= = = = = = = = = = = = = = =
就直接運用期望值可以拆開的概念,全部也只有 $n*(n-1)/2$個子字串,若再多考慮每個字串相同的字母是哪個的至多 $26$ 種可能性去枚舉,最裸的做法時間複雜度是 $O(26n^3)$,但是$s[i...j]$ 全為同一個字母的機率可以由 $s[i...j-1]$ O(1) 轉移得知,所以立刻就壓到 $O(26n^2)$ 了。但實際上這題根本可以做到 $O(n)$,大家可以想想看~。這題算是期望值類的老掉牙的題目吧。

450 --- SuccessiveSubtraction2

題意: 給定一個數列 $a_1 \sim a_n$,考慮算式 $a_1 - a_2 - a_3 - ... - a_n$,我們可以至多家上兩組括號,求最大的可能計算結果是多少。

數據範圍:$1 \leq n \leq 2000$,有至多 $2000$個詢問(每個詢問是把上一筆詢問的其中一個數字改成另外一個數字)。

tag:[ dp ]

關鍵字:最大連續和

= = = = = = = = = = = = = = =
自己亂補上刮號就可以發現,補至多兩個括號,等價於把 $a_3 \sim a_n$ 中至多連續的兩段數字正負對調。

這題做法一堆吧,限制非長寬鬆,加上他每筆詢問實際上只有變動一個數字,那應該是可以做到 $O((q+n) log n)$ 的。

我的做法是 dp 做出每個 prefix 和 suffix 的最大連續和,然後枚舉prefix 和 suffix 切開的位置。

這題還有一個有趣的做法(參考此連結的),先找一次最大連續和的一段正負反過來,然後再做一次相同的事就行了。

850 --- TwoEntrances

題意:給一個長的像 Tree 的家,由兩個 node 是家的入口,現在要搬家具進去每個 node,但是能般進去的條件是,由某個入口到該 node 的 path 上都還沒有放入家具,問般家具的順序有幾種?答案 mod $10^9+7$。

數據範圍:邊數不超過 $3000$。

tag :[ dp ] [ 排列組合 ]

關鍵字:燈飾 dp

= = = = = = = = = = = = = = =

私認為這題難度只有 $500$,若入口只有一個,那他就只是一個非常經典的題目,我這個  BLOG 已經出現過了... 請看 CF290 pD

若是這樣的問題相信不少人都見過,但入口兩個要怎麼處理呢?

先畫意張示意圗 :)

黑點是入口,我們想像一下把代表入口的兩個點釘在牆上掛起來,大概就會變成上圖所示。

我們先想想退化的 case,例如說...掛起來後沒有任何點垂下來。我們會發現,這種 case 的話,任何時刻有擺家具的 node 都是連在一起的!於是就給了我一個靈感,我們可以 dp 狀太設成: $dp[l][r]$ 代表 $p_l \sim p_r$間及其垂下來的所有 node 都擺上家具,但其他 node 都沒有的方法數。

至於要怎麼轉移呢?我們可發現,代表 $dp[l][r]$ 的狀態,最後一個擺上家具的位置一定是 $p_l$ 或 $p_r$ 兩者之一,於是我們分別把 $p_l$ 和 $p_r$ 當作 root,然後想像你是怎麼解原始的經典題版本,那應該就會知道要怎麼轉移了 :)


2015年3月17日 星期二

SRM653 --- 由於題目太過簡單,一不小心比賽結束時也就把解題報告寫完了!

//不知道長標題對搜尋引擎是否會有影響 0.0

相較於前三場 SRM,這場確實簡單太多了!簡單到我都為出題者感到不好意思了 >_<
而且聽說出題者還出了兩個包,這場比賽的出題者也太廢了吧!

點我連到官方題解(必須登入Topcoder帳號)

Div.2 250 --- CountryGroup

題意:有 $N$ 個人坐一排,每個人都恰屬於一個國家(沒有人有雙重國籍唷 >_<),你對這群人有個猜想:同一個國家的人會坐在一起。你想要驗證這個猜想,於是你對每個人都問了這個問題:"包括你,總共有多少人和你來自同一個國家?"。如果能從大家的回答推論出你的猜想是錯誤的,或是你能確定有人的回答是錯誤的,請回傳 -1,否則回傳根據你的猜想,這群人的國家個數。

數據範圍:小小的。

tag:[ adhoc ]

= = = = = = = = = = = = = = =
不管難度,只看題意的話,這題還算有趣吧?解法很單純,先考慮最左邊的人,令他的回答為 $x$,則從他往右算起連續的 $x$ 個人回答也得是 $x$ 才會滿足你的猜想,並把國家數目加一。緊接著把這些人排除,繼續做一樣的事,直到不滿足你的猜想或全部人都排除。

這題以 Div.2 250 來說應該是偏難的,有很多潛在的 bug,但 Sample 非常和譪可親,應該可以幫忙抓出大家大多數的 bug 吧?

順便讓大家想想看這題的變化題:

1.若大家不是坐成一排,而是坐成一個圈,甚至是大家的座位是排列成二維的樣子呢?

2.若同國家不一定要坐在相鄰位置,要怎麼算國家數或判斷有沒有人回答錯誤?

這兩題頂多也只是個 Div.2 500 的題目吧。

Div.2 500 --- RockPaperScissorsMagicEasy

題意:Alice 和 Bob 玩一個紙牌遊戲,每張紙牌上有剪刀石頭布三種圖案中的一種,每種圖案的紙牌都是無限供應的。Bob 會先選一些紙牌排成一列且圖案那一面朝下不讓 Alice 看到,接著 Alice 也會選和 Bob 同樣張數的紙排排成一列,按照順序和 Bob 的紙牌比輸贏,贏的人可以得一分,輸或平手都不會得分。但 Alice 其實有在紙牌背面偷偷做記號,所以 Bob 擺完紙排後,Alice 其實是知道 Bob 擺了些什麼。Alice 想要裝神祕的向 Bob 宣告說:這場遊戲我將會得 $score$ 分!請問 Alice 有多少種不同的紙牌選法使他可以達成他的宣告呢?答案請 mod $10^9 + 7$。

數據範圍:Bob 排的紙牌總數($N$)不超過 $2000$。

tag:[ 數學 ]

= = = = = = = = = = = = = = =
首先,雖然題目會依序給你 Bob 每個位置放的圖案是什麼,但實際上我們只關心每個圖案 Bob 共選了幾張。於是我們可以枚舉對於 Bob 的每個圖案,Alice 各贏了幾張去算排列組合,並且只要枚舉其中兩個圖案贏的張數(令其為 $x$ 和 $y$),就可以推出第三個圖案贏的張數必須是 $score - x - y$。於是我們就有了 O(N^2) 的做法!

看了我以上列的解法應該會覺得我是笨蛋吧 XD 一個有 O(N) 做法的題目竟然被我說的那麼複雜。但說來慚愧,我第一眼見到這個題目後直覺得做法就是這樣 ...,之後看了別人的作法只能直呼小月是笨蛋 >_<

實際上,我們根本不在乎 Bob 選的圖案是什麼,我們只要在當中選 $score$ 張卡讓 Alice 能贏,剩下的卡讓 Alice 不能贏,所以答案是 $C_{score}^n * 2^{n-score}$

Div.2 1000 --- SingingEasy

題意: Alice 和 Bob 要合唱一首歌,方便起見,我們把所有音符的音高用 $1 \sim 1,000,000$ 間的數字表示,並依序給你這首歌每個音的音高。他們合唱的時候,每個音都恰由 Alice 或 Bob 其中一人唱。不難想像,若同一人要唱的兩個音差愈大難度愈高,所以他們想要安排一種唱法,使得兩個人個別唱的所有音依序排列後,相鄰兩個音音高差的絕對值和愈小愈好。例如說有一首歌只有四個音,音高依序為 $1,4,2,5$ ,那我們可以讓 Alice 唱音高為 $1,2$ 的兩個音,Bob 唱剩下的音,這樣的話所有相鄰兩個音絕對值和為 $abs(1-2) + abs(4-5) = 2$ 將是最佳解。

數據範圍:至多 $2000$ 個音符(以 $N$ 表示)。

tag: [ dp ]

= = = = = = = = = = = = = = =
這題應該讀完題就會讓人想要用 dp 去解他吧?我在想這題的時候,瞬間就覺得自己會做了,可是實際上要寫的時候,狀態轉移的部分稍微卡了一下下,離開筆電走路繞圈圈讓自己靜下來後才把轉移搞出來。連兩題 Div. 2 都出了點糗 >_<,大概是因為我對 Div.2 太輕忽了吧...

(註:以下過程我並沒有仔細處理邊界的情況,會發生你完全按照 dp 是寫下去卻可能 WA 掉的情況... 請自行腦補不足的部分 >_<)
這題我 dp 的狀態採用如右:dp[$L$][$R$] 純的最佳解代表只考慮到第 $1$ 到第 $R$ 個音,且唱第 $R$ 個的那個人是從 第 $L$ 個音連續唱到第 $R$ 個音,第 $L-1$ 個音是由另一個人唱。

當然你若要把他想成唱完 $R$ 個音以後,兩個人最後唱的音各是 第 $L - 1$ 個音和第 $R$ 個音也是可以的。

選一個好的狀態去 dp 大概是這題的第一個困難點,下一個困難點就是怎麼轉移了。

轉移分兩種 case:

1. 當 $L = R$ 時:$dp[L][R] = min_{1 \leq i \leq L-1}(dp[i][L-1] + abs(pitch[L] - pitch[i-1]))$
2. 當 $L < R$ 時: $dp[L][R] = dp[L][R-1] + abs(pitch[R] - pitch[R-1])$

雖然第一種 case 的時間複雜度是 O(R),可是這種 case 的狀態數至多只有 $N$。第二種的轉移時間複雜度是 $O(1)$,有 $O(N^2)$ 個狀態。故總時間複雜度是 $O(N^2)$。

至於這題能不能做到比 $O(N^2)$ 更快呢...咦?似乎可以做到 $O(N)$ 唷!難道說 $N$ 變更大就是 Singing 的題目嗎!?讓我們拭目以待 ^ ^

Div.1 250 --- CountryGroupHard

題意:有 $N$ 個人坐一排,每個人都恰屬於一個國家(沒有人有雙重國籍唷 >_<),已知同個國家的人都坐在一起。有一個記著想要問每個人這個問題:"包括你,總共有多少人和你來自同一個國家?"。這個記者已經問過一些人了(問過的人可以是任意子集),他想知道他到底有沒有必要在繼續問下去,還是說其實已經可以推論剩下的所有人的答案呢?

數據範圍:小小的。

tag:[ dp ]

= = = = = = = = = = = = = = =
看到 tag 的話這題就直接被雷爆了吧?看到這意題的第一眼,我大概想了一分鐘要怎麼去 greedy 判斷,一直想不出來,後來轉念一想,我們根本可以 dp 出所有人的回答的可能性的方法數吧...(諸如這樣,根本可以算出個數,但只問你Yes/No的題目還蠻常出現的),於是就沒多想地隨便寫了個 $O(N^3)$ 的 dp 了。

可是我設的 dp 狀態頗蠢的,我竟然開了三維陣列 $dp[x][y][z]$,代表只考慮前面 $x$ 個人時,第 $x$ 個人是某群共 $y$ 個人的國家的第 $z$ 個人的方法數。總時間複雜度是 $O(n^3)$。

更多人 dp 狀態應該只會開一維 $dp[x]$ 代表只考慮前面 $x$ 個人時,第 $x$ 人恰好是同國家的某群人的最後一個人的方法數。可以輕鬆做到 $O(n^2)$。

而事實上,這題可以做到 $O(n)$!並不難,大家可以想想看~

Div.1 450 --- Singing

題意: Alice 和 Bob 要合唱一首歌,方便起見,我們把所有音符的音高用 $1 \sim N$ 間的數字表示,其中 Bob 的音域在 $[1,high]$,Alice 的音域在 $[low,N]$。依序給你這首歌每個音的音高。他們合唱的時候,每個音都恰由 Alice 或 Bob 其中一人唱(當然要符合唱的人的音域)。且相同音高的音符必須同一個人唱。為了使合唱的難度變低,他們希望唱的過程中,"換手"的次數最少,一次"換手"是指相鄰兩個音由不同人唱。

數據範圍:至多 $1000$ 個音符。

tag: [ min-cut ]

= = = = = = = = = = = = = = =
咦,這題不是 SingingEasy 的範圍加強版啊...難道說 $O(N)$ 的做法是我想錯了嗎 >_< 這兩題還差蠻多的 Orz

SRM 偶爾會有像這樣子相當裸的 flow 類的題目,由其這題的 input 處理相當簡單,有經驗的選手讀題加寫題不需要 5 分鐘。但是對 flow 若不熟悉,這題或許會想歪吧?可是我身為一個曾經花時間研究過各類 flow 題的人,無法想像這題能想歪成什麼東西。(後來聽別人說有想歪到 dp 去。)

總之這題就是把每個音高都當成一個點,任兩個點會建一條 cost 為 "這兩個音高相鄰的次數" 的邊。我們就能把此問題轉換為:要把所有點都 label 成 Alice 或 Bob,並且已經知道某些點的 label,使得連結相異 label 的邊的總 cost 最小。

超有 min-cut problem 的感覺對吧!就好像要我們找一個最小 cost 的 cut,使得此 cut 的一邊被 label 成 Alice,另一邊被 label 成 Bob。

確切的建圖方法為:除了有出現的 pitches 當做點以外,在另外建出一個代表 Alice 的 source 和代表 Bob 的 sink,並且把 source 建 cost 為無窮大的有向邊到確定是 Alice 唱的音高的點,也把所有確定是 Bob 唱的點連一條 cost 為無窮大的邊到 sink,最後再把上一段所提到的邊必須兩個方向都建一條相同 cost 的邊,於是就大功告成了。可以想想看為什麼這樣建出的圗是對的。

如果擁有 2014 ioicamp 的講議的人,可以翻到例題 7-8,是比這題還更裸的問題 XD

最後再給一個相同概念但稍為複雜些的題目:SPOJ839 Optimal Marks 做為練習。

Div.1 900 --- RockPaperScissorsMagic

題意:Alice 和 Bob 玩一個紙牌遊戲,每張紙牌上有剪刀石頭布三種圖案中的一種,每種圖案的紙牌都是無限供應的。Bob 會先選一些紙牌排成一列且圖案那一面朝下不讓 Alice 看到,接著 Alice 也會選和 Bob 同樣張數的紙排排成一列,按照順序和 Bob 的紙牌比輸贏,贏的人可以得 $win$ 分,平手各得 $even$ 分,輸的人得 $lose$ 分。但 Alice 發現其實有人在 Bob 的紙牌背面偷偷做記號,相同圖案的紙牌都被標了相同的數字($0 \sim 2$)做為記號,但是 Alice 不知道哪個數字對應到哪個花色。Alice 想要根據這些記號來出牌,並向 Bob 如表演魔術般的宣告說,他知道最後自己會得幾分。請問 Alice 有多少種不同的表演方法?只要他宣告的分數不同或是出的牌的序列不同就算是不同表演方法。答案請 mod $10^9 + 7$。

數據範圍:Bob 排的紙牌總數($N$)不超過 $1000$。

tag:[ 數學 ]

= = = = = = = = = = = = = = =
這題好像也和 RockPaperScissorsMagicEasy 差很多...(以解法而言)

實際上這題頗簡單的,會覺得他難的話大概只是題目敘述複雜了點?首先同樣的我們不關心 Bob 排的那些牌的順序,只關心每種記號的牌各有幾張,並令 $n_i$ 為被標記為 $i$ 的張數。

接著我們先想想看裸的做要怎麼做。應該會想到此做法:對於每個記號,都枚舉出各 Alice 各種圖案各出多少數量。也就是說,枚舉 Alice 對於標號 $0$ 的牌出了 $a$ 張剪刀,$b$ 張石頭,$n_0-a-b$ 張布;對於標號 $1$ 的牌出了 $c$ 張剪刀,$d$ 張石頭,$n_1-c-d$ 張布;對於標號 $2$ 的牌出了 $e$ 張剪刀,$f$ 張石頭,$n_2-e-f$ 張布。最後在枚舉 $3!$ 種標號和簡刀石頭布的配對方法,看看得分是否一樣。這樣的暴力做法複雜度約是 $O(N^6)$。

這做法能化簡嘛?還是要另闢出路呢?例如說根本就只有少數 special case 有可能使得 Alice 有宣告方法?不管怎樣,我們還是先列出對應的數學的式子如下:



等號左邊的變數意義都如同前面所述,而等號右邊 $A_{ij}$ 的意義為:在枚舉完後,若標為 $j$ 的卡片實際上是 $i$ ($i=0$:剪刀,$i=1$:石頭,$i=2$:布),Alice 對抗所有此類卡片的總得分。

而所有 $3!$ 種可能標號配對方法都一樣意思就是矩陣 $A$ 中每行每列恰取一個數的和都要一樣。

列到這裡先停頓一下看看大家對做法是否有感覺了~

直覺敏銳的人應該就會注意到 "所有 $3!$ 種可能標號配對方法都一樣意思就是矩陣 $A$ 中每行每列恰取一個數的和都要一樣。" 這句話還有更和譪可親的形式!每行每列恰取一個數的和都一樣意即 "無論取哪個 column,相同的兩個 row 的值的差是固定的!"。也就是說對於任意 $i,j$,$A_{i0} - A_{j0} = A_{i1} - A_{j1} = A_{i2} - A_{j2}$。

提示到這裡應該有不少原本不會的人知道要怎麼做了吧?原本我們要同時枚舉 $a~f$,但我們也可以 $a,b$ 一組,$c,d$ 一組,$e,f$ 一組分開枚舉,每組個別枚舉完恰會對應到 $A$ 矩陣中的一個 column,我們的問題變成要求三組算出來的 row 的差值都一樣的組和有幾種,於是可以使用 hash 在 $O(N^2)$ 的時間做到。


= = = = = = = = = = = = = = =
這篇讀完應該能讓大家相信我說的這場 SRM 很簡單吧 XD 我覺得題目敘述本身會令人覺得還蠻有趣的啦,只是真的偏簡單就是了 0.0

2015年3月10日 星期二

SRM652

因為 250pt 的 Sample壞掉了而 unrated,已經連續兩場 unrated 了,總覺得最近 Topcoder 諸事不順。

這場我也是先開了 1000 pt 的題目看,試了一陣後發現比賽結束前大概無望弄出來,就回去看250 pt 和 500 pt 的題目,這時只剩 20 分鐘,迅速寫完 250 pt 後,500 pt 一看就知道大概怎麼做了,只是沒有時間把細節弄清楚和寫完 (這題很重邏輯推理,實際上大概還差個至少 20 分鐘的時間吧...) 看來要寫完 250 pt 和 500 pt,至少要保留 40 分鐘比較穩定。

250 --- ThePermutationGame

題意:Alice 和 Bob 玩一個遊戲如下,Bob 可以決定一個前 $N$ 個自然數的 permutation function $P$ (意即 $P$ 的 定義域即值域都是前 $N$ 個自然數,並且為一對一且映成的函數)。而 Alice 可以決定一個數 $x$,Alice 決定的數必須使得無論 Bob 決定的函數為何,把 $1$ 迭代這個函數 $x$ 次後仍是 $1$(意即 $P(P(...P(1)))=1$,共 $x$ 個 $P$),給定 $N$ 請問 $x$ 最小是多少?(答案 mod $10^9 + 7$)

數據範圍:$1 \leq N \leq 100,000$。

tag:[ 數學 ]

= = = = = = = = = = = = = = =
我讀完題目後瞬間就把題目理解成是求前 $N$ 個自然數的最小公倍數了,因為對於同一個數 $i$ ,令 $i$ 迭代 $P$  $x$ 次的結果是 $a_x$,則 $a_x$ 一定是從頭開始循環的,而且循換節長度 $1 \sim N$ 都有可能,$a_x$ 要變回 $i$,$x$ 必須是循環節長度的倍數。

至於要怎麼求 $1 \sim N$ 的最小公倍數呢?我的方法是直接求出所有質數在 $1 \sim N$ 裡出現的最高次數,就可以推到答案了。

根據你的寫法,可能有些變數必須開 $64$-bit 整數,我成功的 challenge 一份該開 $64$-bit的地方只開 $32$-bit 的 code。我時常在想 ... 為什麼不要萬物都 $64$-bit?一直有人因為這種蠢 bug WA真令人感到難過。

500 --- MaliciousPath

題意:Alice 和 Bob 在有向圗 $G$ 上玩一個遊戲如下:最初 Alice 在編號為 $1$ 的點,每一輪,Alice 可以選定一個可走的邊,並走過去,目標是走到編號為 $N$ 的點,每個邊都有對應的 cost。而 Bob 有 $K$ 個 Token,每ㄧ輪 Alice 決定要走哪條邊後,Bob 都可以決定要不要使用 Token,使用的話就可以強制改變 Alice 這輪要走的邊。Alice的目標是希望到達點 $N$ 所需的 cost 總和盡量少,而 Bob 則希望盡量多。請回傳兩人都使用最佳策略時的 cost 總和值,若 Bob 有辦法讓 Alice 永遠走不到終點,則回傳 $-1$。

數據範圍:$2 \leq N \leq N$,邊數不超過 $2500$,每條邊 cost 介於 $0 \sim 1,000,000$,$0 \leq K \leq 1,000$。

tag:[ 最短路 ]

= = = = = = = = = = = = = = =
看完題目和數據範圍後,大概就知道是最短路的變形題了,但細節嘛... 我沒辦法馬上想清楚 OAQ第一名只花了 $10$ 分鐘 AC 了好厲害 0.0而且它 code 超短。

首先想想 $K$ 是 $0$ 時會發生什麼事,毫無疑問就是個單純的點 $1$ 到點 $N$ 的最短路吧?接下來若 $K$ 是 $1$ 呢?基本上我們可以相信,若會做 $K$ 是 $1$ 的情況,就幾乎等於解決這題了因為感覺起來從$K = i-1$ 推到 $K = i$ 的方法,無論 $i$ 是多少都是一樣的。

令 $dp[k][x]$ 代表 Bob 還剩 $k$ 個 Token 並且 Alice 在點 $x$ 時的答案,另外我們也可推論,當 Bob 要使用 Token時,一定會選擇所選的邊 $(x, y)$ ,使得此邊的 cost 加 $dp[k-1][y]$ 值最大,我們令這個值為 $g[k][x]$。

根據 Alice和 Bob 的策略,我們可以列出以下關係式:

$dp[k][x] = \min_y{ \max (g[k][x], cost[x][y]+dp[k][y])}$ (若 $x$ 沒有指向 $y$的邊,cost[x][y]視為無限大)

但麻煩的是這個關係式並沒有特定的順序可以好好 dp,但有沒有發現這個關係式其實和某個東西很像呢?嗯...基本上就只是最短路的關係式多包一個 $\max (g[k][x], *)$,於是我們何不試著用類似 dijkstra 的方法去解決它?根據這個關係式,我們要把邊反向,並且改成用點 $N$ 當做起點。若你有猜到這一步,那基本上就可以 AC 這題了(可參考我附的 code 連結)。但我們不要滿足於此 >_< 來繼續證明它是對的。

證明的方法其實也和 dijkstra 的證明差不多,重點在於,關係是裡 $\max (g[k][x], *)$ 這部分只會使最短路的值更大而不會更小,確認了這點後就可以完全套入 dijkstra 的證明了。請不要嫌棄我這樣的解釋太單薄 >_<

1000 --- NoRightTurn

題意:平面上有 $N$ 個點,並且任三點不共線,給定起點後,我們要走訪所有的點,兩點之間必須走直線,且過程中不能右轉,只能在有點的地方轉彎,以及所走出的 polyline 不能和自己嚴格相交,請回答每個點當做起點有多少種走法。答案要 mod $10^9 + 7$

數據範圍:1 \leq N \leq 100,座標的絕對值不超過 $1,000$。

tag:[ 計算幾何 ][ 凸包 ][ 構造 ]

= = = = = = = = = = = = = = =
這題在比賽間,我只猜到答案很小,於是我想要模擬以及判別當前還能不能繼續走下去來搜索答案數,只是我想了一些判別方法都想錯了 @@。後來看了  Codeforces 的討論串,發現我方向大至正確,但這題的結論比我想像的還要強,比起搜索這個字眼,用構造應該會比較貼切。而且考慮任意點當起點的 polyline 總數只與 $N$ 和凸包上的點數有關。又或者說,沒有想到凸包的話,這題根本很難想下去 (我在賽中我全沒有想到凸包這回事 @@)

先看看這張圖:

藍色的點是凸包上的點,紅點則是其餘的點,多畫幾張你就會發現,凸包上的點在 polyline 裡是連續的!再來你會發現第二件事:總是可以畫出ㄧ條直線把 polyline 上被把藍點隔開的兩群紅點,也用一條直線隔開且線會通過凸包開口 (如圖中的紫色直線)。最後,還有一件事:若決定好凸包上的開口以及裡面紅點分兩群的方法,那將只有唯一一種畫 polyline 的方法!

以上所述的證明就略過吧@@應該沒有很難?

把這些事實當做已知後,就會發現解題的重點要放在如何找到開口以及如何枚舉所有的紅點分兩群。

先思考一個相對簡單的問題:平面上有 $N$ 個點,任三點不共線,要把這些點完整分成兩群,每群都至少一個點,使得可以用一條直線把這兩群分開,共有幾種分兩群的方法?

手動畫一些 $N$ 比較小的case後,應該就會猜到答案是 $C^N_2$ 了。雖然容易猜得到答案,但如果要你把所有分法都列出來呢?那只好來好好的構造答案了。
對於每種粉兩群的方法,我們種是能把分隔兩群的直線一直順時鐘旋轉,直到恰碰到兩群各一個點如上圖。考慮碰到的兩個點,應該不難看出碰到的兩點以及分群的方法的一對一對應的關係。

迴到原來的問題,現在我們已經知道如何把點分成兩群,那只要再枚舉開口判斷和不合法,再用類似凸包的方法,模擬出 polyline 的起點在哪就行了!這樣時間複雜度會是 O(n^4) 說是這樣說,可是 code 寫起來大蓋很痛苦吧XD 要如何判斷開口和不合法可能也令人要多思考一些時間。

不過參考 writer 的 code 後會發現,其實有一種枚舉兩個點的方法,可以把開口在哪也一並枚舉出來,相較前述方法好寫多了,大家可以想想看要怎麼樣做到這件事 ~

p.s. 由凸包上的頂點當做起點的 case 當做特例處理大概會比較方便


2015年2月28日 星期六

SRM651

又是cgy4ever的題目!他題目產量好多喔!不過這場不僅 Unrated ,而且賽中 也不能 submit 了有點難過,不過還是來寫寫我看完題目後想到了什麼吧。

作者的 short editorial

250 --- RobotOnMoon

題意:有一個 $n * m$ 地圖,有些格子被障礙物擋住了,有一個機器人並給你他初始位置,你可以設計一些指令讓他行走,若指令叫他往某個方向走,那個方向卻被障礙物擋住,那機器人不會移動。若執行那個指令會走出地圖外,那他就走出地圖外了 0.0 這機器人壞壞的,所以每個指令他都有可能會不小心 miss,現在我們要設計最長的上下左右的指令讓機器人無論 miss 了任何 subsequence 都一定不會走出地圖外。

數據範圍:小小的

tag : [ adhoc ]

- - - - - - - - - - - - - - -

看完題目後立刻想到若上下左右的某個方向直直走會被擋住,那就可以設計一個無限長的那個方向的指令。並且很容易相信這是僅有的答案為 -1 的 case,至於答案不是 -1 的 case 嘛...,其實我最剛開始猜的是上下左右最長的長度,可是看了一下 Sample,發現所有 Sample 都會對而且都是以這個做法來說很極端的 case... (要碼答案是 -1 要碼四個方向長度非 0 的只有至多一個方向)。就覺得答案一定不是這樣,在花幾秒後就想到正解而且發現可以輕易證明它了。不過說真的 ...這種題目若測資太強就太容易猜答案結果就不好玩了 XD


500 --- FoxConnection3

題意:平面座標上有 $n$ 個點,要上下左右移動它們,使得它們變為連通,並且這 $n$ 個點的移動步數和最小。每次移動都只能上下左右選其一移動一格,並且 always 不能有兩個點重疊。

數據範圍: $n \leq 6$,座標絕對值不超過 $10^9$。

tag:[ 枚舉 ] [ 數學 ]

- - - - - - - - - - - - - - -

類似題其實蠻常見的,最常見的就是在一維空間上做同樣的事,二維空間的類題我也立刻想到一題 HOJ84。不能重疊的什麼根本不用管這個條件,我以前思考過類似的事情了。最後再看到 $n$ 最大只有 $6$。顯然可以暴力枚舉所有連通圖的點塊的樣子。所以說這題我讀完題目瞬間就知道這麼做了,只是 code 似乎不夠好寫就是了。但 Petr 好厲害寫好快 0.0 到底怎麼辦到的 ...

1100 --- FoxAndSouvenir

題意:有 $n * m$ 的矩陣,有些位置有值有些沒有,有 $q$ 組詢問,第 $i$ 個詢問給你一個矩形,問你這個矩形內有幾種選數值的方法使得這些數值的總和為 $v_i$,答案 mod $10^9 + 9$。

數據範圍: $1 \leq n, m \leq 50$, 矩陣內數值總和 $\leq 2500$。

tag:[ 傅立葉 ]

- - - - - - - - - - - - - - -

SRM 久違的傅立葉題...,但這題我看完第一個想到的是這題:Good Bye 2014 --- New Year Shopping,把它變成 2D版,所以我就一直往 D & Q 加 根號類算法下去想了 ...然後還自以為想到但後來發現某個地方複雜度搞錯了。

其實我應該要特別注意到 $10^9 + 9$ 這個數字的,向來當題目不 mod $10^9 + 7$,而是 mod $10^9 + 9$,通常都有特殊用意,所以看到這個數字就可以先往很數學的方向想少陷入些坑坑洞洞,不過我對傅立葉還不熟就是了,過高級的應用不太可能在一兩個小時內想到...。

- - - - - - - - - - - - - - -

下一場 SRM 要等到 3/9 了 ...,不要一直壞掉啦 OAQ

2015年2月2日 星期一

SRM648

這場 SRM 雖然我拿了 -25 分...但還是照寫題解XD
都怪我一剛開始 850 想歪,並且剩 25 分鐘時才去開 550,剩一分多鐘才把 code 寫完而且沒能de 到某個蠢 bug @@

250 --- AB

題意:請構造出一個由 A 和 B 組成長度為 $L$ 的字串,使得 A 在 B 的左邊的組數恰好為 $K$,沒有的這樣的字串存在則回傳空字串

數據範圍:小小的

tag:[ greedy ]

= = = = = = = = = = = = = =

若 A 的數量固定,可以想像所有 A 在所有 B 的左邊時組數會最多,並且數量為 $k*(L-k)$ ($k$ 為 A 的數量)。故組數最多的情況發生在 $k = L/2$。

接著我們可以發現,若存在某個A在某個B的左邊相鄰位置,我們把這兩個相鄰的 AB 交換後,可使 A 在 B 的左邊的組數減 $1$,並且若當前組數不為 0,總是可以找到這樣的相鄰的 AB。

有以上結論,應該就能解出這題了。

550 --- KitayutaMart

題意:一個商店裡有 $K$ 種商品,你所買的第 $k$ 個第 $i$ 種商品要花費 $i \times 2^{k-1}$ 元,你總共要買 $N$ 個商品,希望最貴的一項商品價錢最少,請輸出此價錢 mod $10^9 + 7$

數據範圍: $1 \le N, K \le 10^9$

tag:[ 數學 ][ 二分搜 ]

= = = = = = = = = = = = = =

我的思考邏輯如下:


首先注意到,若某項商品買了比另外一項商品多了至少30個則一定比較貴,所以買的任兩種商品的數量差一定不超過 $30$。

於是我們就可以估計出,最貴的那項商品所買的商品數範圍,一定落在 [$N/K - 100$,N/K + 100] 之間 (對不起我的腦帶無法快速算出更精確的範圍,就隨便給一個一定會對的區間...)。

接著我想對所有可能的 $k$ 試試看,最貴的商品是否可能是第 $k$ 個某商品,由於同種商品的第 $k$ 個的價錢是嚴格遞增的,自然而然的就想到要使用二分搜,於是,在二分搜時我們要判斷:價錢不超過第 $k$ 個第 $i$ 種商品的有幾個,我們能因此找到最小的 $x$ 滿足價錢不超過第 $k$ 個第 $x$ 種商品的個數為 $N$ 個以上,接著我們再計算價錢恰巧和第 $k$ 個第 $x$ 種商品一樣的有幾個,就能知道有第 $N$ 個商品的價錢是否和第 $k$ 個第 $x$ 種商品一樣。

我們剩下兩個問題要解決:1.價錢不超過第 $k$ 個第 $i$ 種商品的有幾個  和 2.價錢恰巧和第 $k$ 個第 $x$ 種商品一樣的有幾個。

第二個問題應該是比較簡單的。我們知道所有的整數數對 $(a, b)$ 若 $a$ 為正且 $b$ 介於 $1$ 和 $k$ 之間,則恰對應到一個價錢是 $a * 2^{b-1}$ 的商品,所以我們只要枚舉所有可能的 $i$ 使得 $(x*2^i, k-i+1)$ 仍是合法的數對,就能知道第二個問題的答案了,數量一定不超過 $30$ 個。

而知道了第二個問題的答案,離解第一個問題也不遠了,因為同樣是第 $k$ 個同種商品,且價錢不超過第 $k$ 個第 $i$ 種商品的個數就是 $i$。於是用類似解第二個問題的方法也可解第一個問題。

850 --- Fragile

題意:有編號的 $N$ 個點所形成的無向圖,有多少種橋的個數是 $K$?所謂的橋是指移除後圖的連通塊個數會增加的邊。

數據範圍:小小的

tag:[ 數學 ][ dp ]

= = = = = = = = = = = = = =

這種題目還蠻常見的,各種各式各樣的圗的技術問題,舉例來說,也有問題是問你 $N$ 個點的樹 (tree) 有幾種?或問你 $N$ 個點的連通圖有幾種?甚至問你 $N$ 個點的強連通有向圖有幾種?
之前有在網路上看到一篇投影片是在介紹各種類似的問題,不過我一時間找不到...

這題由於數據範為小小的,所以你使用高複雜度的 dp 都是可解的,大不了花個十幾分鐘跑完程式後把結果印在 code 裡(例如 Petr 的 code)。我自己賽後想到的式O($N^5$)

不過根據我對 writer 的 code的考據,他使用了最高為O($N^4$)的時間複雜度作了總計三次 dp。

(以下所謂的圗都是有編號的 (labeled))

第一次:求出 $N$ 個點的所有點都連通的圖有幾種。時間複雜度為O($N^2$)。

$dp1[i]$ 紀錄點數為 $i$ 的連通塗有幾種。
首先我們知道 N 個點的圗共有 $2^{N*(N-1)/2}$ 種,意即每個邊可選或不選。而若能扣掉部連通的圗的個數,就可以求出連通的圗的個數了。所以我們就枚舉和邊號 $1$ 的點連通的點數,從 $1$ 枚舉到 $N-1$,個數分別是 $dp1[i] * 2^{(N-i)*(N-i-1)/2} * C(N-1, i-1)$

第二次:求出 $N$ 個點的所有點都連通且有 $K$ 個橋的圗有幾種。O($N^4$)。

$dp2[i][j]$ 紀錄 $i$ 個點 $j$ 個橋的種類數。
$j = 0$ 的時,我們一樣試著用 $dp1[i]$ 去扣掉所有 $j$ 非 $0$ 的值。
對於 $j$ 不為 $0$ 的情形,我們使用一種 counting 的技巧 --- 讓同一張圖重複算好多次,但被算到的次數是一樣的,就可以把結果除以同張圖被算到的次數來得到答案。
實際上就是,我們計算編號 $x$ 和編號 $y$ 的點中間有橋的個數,若此座橋移除後,和點 $x$ 連通的點數有 $u$  個且含有 $r$ 座橋,則和點 $y$ 連通的點有就有 $i-u$ 個以及有 $j-r-1$ 座橋,這是我們可以 $O($1$)$求得的東西而且不管 $x$ 和 $y$ 是選哪兩個點結果都一樣,最終同一個圖都恰被算到 $j$ 次(因為 $j$ 座橋恰被枚舉到一次)。把我上面所述的綜合起來,會發現是個 O($N^4$) 的式子。

第三次:求出 $N$ 個點恰 $K$ 個橋的圗有幾種(即最終答案)。 O($N^4$)。

已經有了第二次dp的結果,這部分應該就容易多了,我就不解釋了。