Topcoder口胡記 SRM 562 Div 1 ~ SRM 599 Div 1


據說做TC題有助於提高知識水平? :)

傳送門:https://284914869.github.io/AEoj/index.html

轉載請注明鏈接:http://www.cnblogs.com/Blog-of-Eden/p/8407296.html

Topcoder SRM 562 Div 1 - Problem 1000 InducedSubgraphs

當K*2<=N的時候,顯而易見的是編號為i(K<=i<=N-K+1)的點一定會形成一條鏈。

枚舉合法的這樣的鏈,剩下的暴力dp吧。

當K*2>N的時候,顯而易見的是編號為i(N-K+1<=i<=K)的點一定會形成一個聯通快。

如果把這個聯通塊去掉,樹會形成若干個不相交、不接觸的小聯通塊,且這些聯通塊的大小之和一定。

如果把樹的一個點提根,進行上下dp,就能很方便地進行統計答案。

Topcoder SRM 563 Div 1 - Problem 950 CoinsGame

好慘慘啊!這么簡單的題竟然沒有自己想出來~~

我們稱棋子A和棋子B等價,當且僅當它們只會同時在這個棋盤上,或同時離開棋盤。

一個顯然的結論就是,若A和B等價,B和C等價,那么A和C等價(即具有傳遞性)

所以可以通過bfs求出所有等價點對,通過並查集合並。用總情況數減去不合法情況數就好了。

Topcoder SRM 564 Div 1 - Problem 850 DefectiveAddition

topcoder罕見的水題啊!

如果我們已知了每個數相與原數不同的最高的二進制位,(設ta為pi)

那么對於第k位,如果有x個數滿足pi>k,由於這些位的異或值確定,

所以,當x>0時,有2^(x-1)種方案。

由於當x=0時會有意想不到的事情發生,所以稍微dp一下就好了。

Topcoder SRM 565 Div 1 - Problem 1000 UnknownTree

topcoder罕見的無思維難度碼農題。。

分兩種情況討論:A、B、C在同一條鏈上。以及A、B、C不在同一條鏈上。

Topcoder SRM 566 Div 1 - Problem 1000 FencingPenguins

http://www.cnblogs.com/Blog-of-Eden/p/7852426.html

Topcoder SRM 567 Div 1 - Problem 1000 Mountains

一道很妙的題哇。

一個顯而易見的結論是,一座山的可見范圍,一定是一段連續的區間。

考慮編號從大到小的放置山。

如果當前山可見,並且可見范圍不是從最左邊到最右邊。

那么又有一個很顯然的結論,當前山只有兩個合法位置。

考慮如果當前山不可見,那么這座山對之后要放的山沒有絲毫影響。直接乘上這座山合法的位置數即可。

如果這座山到處都可見?這是個較嚴重的問題,

我們考慮,把所有這樣的到處都可見的山全部拿出來。(按照編號從小到大)(我們稱之為大山)

相鄰兩座大山之間夾着若干個小山。

對於大山L和大山R,(L<R),很顯然1到L-1和R+1到n的山對這之間的山的放置沒有影響。

所以可以枚舉相鄰兩個大山的位置,對之間的小山位置進行dfs。

dfs的復雜度是2的冪次,可以接受。

Topcoder SRM 568 Div 1 - Problem 1000 DisjointSemicircles

異常興奮!又一道喜聞樂見的分情況討論題!

我們設有m對連線已經確定。(m<=n)

當m比較大的時候,暴力似乎行。O(2^(2n-2m-1)*C(2n-2m,n-m))

當m比較小的時候,枚舉這些連線分別在上方還是在下方。

方案合法當且僅當這個半圓里面與它同向的點的數量是偶數。

設向上為1,向下為0,一個半圓相當於限制了這個半圓之中的變量的xor值為1或者是0.

對於前綴xor數組,相當於限制了兩個位置上的數xor為1或者是0。

這個用並查集來檢查一下是否合法即可。

Topcoder SRM 569 Div 1 - Problem 1000 MegaFactorial

我真是個愛學習的孩子,在秋游的時候還在想這道題~~

簡單來說,由於B<=10,我們只關心的是B的最小質因子p以及它的指數q。

簡單的說,我們只要統計N!K的值中,質因子p的指數Q,計算Q div q就好了。

由於對1e9+7取模,div比較麻煩,所以:Q div q = (Q - Q mod q) / q

再由於K比較小,所以矩乘一下就行了。

Topcoder SRM 570 Div 1 - Problem 900 CurvyonRails

誰來治一治我普及組級別的網絡流水平啊o(╥﹏╥)o

復雜地來說,黑白染色,每個格子拆成兩類點:橫方向點和縱方向點,

由於兩份流量都流入橫方向點或都流入縱方向點都會產生1的費用,

所以將方向點拆點,連兩條邊,一條流量為1,費用為0;另一條流量為1,費用為1。

Topcoder SRM 571 Div 1 - Problem 1000 CandyOnDisk

Topcoder也會出這種無腦題?

若a能到達b,那么b也能到達a。

如果從一個圓到達另一個圓,其可到達范圍是兩個圓環。

每個圓環當作一個點,就可以建圖跑spfa。

需要特判一些特殊情況(*/ω\*)

Topcoder SRM 572 Div 1 - Problem 1000 NextAndPrev

枚舉分界點,貪心求最小代價就行了?

由於口胡我可能沒想清細節。。

Topcoder SRM 573 Div 1 - Problem 850 WolfPack

以我的智商看來是做不動這種腦洞題啊。

每次x可以+1,-1,不變,y也可以+1,-1,不變,且x,y至少有一個變,這個很煩啊。

根據題解的做法,我們把坐標軸旋轉45°,題目變成了:

每次x可以+1或-1,y也可以+1或-1,且x,y獨立!這一步轉化好妙啊!

接下來就好做了,對於一個終點Z,

對於Zx,可以求出x方向上的方案數;對於Zy,可以求出y方向上的方案數。

答案是sigma Zx,Zy [Fx(Zx)*Fy(Zy)] = sigmaZx[Fx(Zx)] * sigmaZy[Fy(Zy)]

TopCoder SRM 574 Div 1 - Problem 1050 Tunnels

對於給出矩形中的非從左邊連到右邊的地道,這些地道會形成括號序列,

對於從左邊穿到右邊的地道,可能是從左往右,也可能是從右往左?

從上往下進行dp?

似乎怎么想也想不清啊。。反正是口胡,放棄思考了。。

TopCoder SRM 575 Div 1 - Problem 1000 Tunnels

每次想網絡流題都要想好久好久~~。。

先進行黑白染色,由於L字形角落的格子一定黑色,兩端的格子一定白色,

兩端的格子,一定有一個在奇數行,一個在偶數行。

源點流向奇數行,偶數行流向匯點就行了。

TopCoder SRM 576 Div 1 - Problem 900 CharacterBoard

Topcoder罕見的放松題啊。

我們考慮給你的矩陣中兩個元素x和y,若它們在字符串中的位置相同才可能發生沖突。

位置相同當且僅當x和y的位置差能被Len整除,這樣的len最多只有i0*j0*sqrt(i0*W)種

對於這樣的每一種len,暴力判斷是否合法以及計算方案數,

如果不存在這樣的沖突,方案數為26^(Len - i0*j0)。所以等比數列求和即可。

TopCoder SRM 577 Div 1 - Problem 1000 BoardPainting

又是網絡流。┭┮﹏┭┮

好難哇,怎么做啊。。

在此給出周欣的算法:

如果把相鄰兩個格子之間新建一個虛點,選擇這個虛點,就表示這兩個格子在一次染色中完成。

由於染色過程不能轉彎,這限制了一個格子橫放向上的虛點和縱方向上的虛點不能同時選。

這就是二分圖最大獨立集問題,可以用網絡流解決

TopCoder SRM 578 Div 1 - Problem 1000 DeerInZooDivOne

看到題目描述中的鹿角,莫名想到喬巴~~

簡單地說,可以枚舉兩個聯通塊之間的分界邊,然后進行dp,

考慮f[a][b]表示以a為根節點,b為根節點,a聯通塊與b聯通塊同構的最大大小。

a的若干個兒子和b的若干個兒子一一匹配,其f值的和+1就是f[a][b]。

這就是二分圖最大權匹配

TopCoder SRM 579 Div 1 - Problem 1000 RockPaperScissors

如果當前我們知道了對手之前扔出a個剪刀,b個石頭,c個布,我們可以通過dp預處理求出下一次對手扔剪刀、扔石頭、扔布的概率。

然后我們當前做出最優決策,使這一回合的期望得分盡可能的大。這也是一個dp。

TopCoder SRM 580 Div 1 - Problem 1000 WallGameDiv1

簡單博弈,我們可以證明,Rabbit不會將棋子向上移, 

當Rabbit在某一行,且下方有障礙時,Eel不會放障礙,

以此我們得出一個結論,Rabbit在一行中的運動是,左,右,左,右,左,......最后下。

我們還可以得出一個結論,當Rabbit在某一行某一列上,且此時Eel沒有在它下方放上障礙,那么Rabbit也一定會往下走了(往左右走之后還一定會回到這里)。

所以可以用區間dp。f[i][L][R][0 or 1]表示第i行,已經放了L到R的障礙(即Rabbit已經走過了L到R),此時Rabbit在L-1還是在R+1。

每次Eel決定Rabbit下方是否有障礙,如果有障礙,則Rabbit決定往左或往右。

據說cwy用奧妙重重的騙分方法A了此題?說不定那也是對的喔。。

TopCoder SRM 581 Div 1 - Problem 900 YetAnotherBoardGame

據說暴力的復雜度是對的??

如果當前行之前的行已經確定,當前行的上一行中有一些還是白色,

它限制了當前行的某些列必須進行操作,其他列必須不操作。

對於這些列,如果以前有過操作,那么當前的操作種類已經確定。否則當前有兩種選擇:操作1和操作2。

復雜度證明:

假設有m列進行過操作。每一列最多會產生一次兩種選擇,復雜度2^m。

由於m列是在M列中選擇的。枚舉子集中的子集復雜度是3^M。

TopCoder SRM 582 Div 1 - Problem 1000 SemiPerfectPower

參考了VFK的題解(http://vfleaking.blog.163.com/blog/static/174807634201352023221271/)

好妙的數論題哇。

首先我們發現只要計算b=2和b=3的半完美數即可。因為b>3的半完美數都可以用b=2或3來表示。

假設P2(x)表示x中不含平方因子。P3(x)表示x中不含立方因子

我們可以用P2(x)表示b=2的結果,P3(x)表示b=3的結果。

最后一步就是求出可以用b=3表示,但不能用b=2表示的半完美數的個數。

如果能表示成b*y^3(且P3(b)=True)。那么b*y^3 = (b*y) * y^2

再假設k^2|(b*y),且P2(b*y/(k^2))=True(即k^2是b*y的最大的平方因子)

那么可以表示成:b*y/(k^2) * (y*k)^2。所以b*y/(k^2) >= (y*k),即b>=k^3

初步列出式子:

我們發現,這個P2(b*y/k^2)不太好處理。

所以企圖把它拆掉。

設k' = k^2 / gcd(k^2,b);

b' = b / gcd(k^2,b);

y' = y / k';

P2(b*y/k^2) = P2(b'*y/k') = P2(b' * y') = (P2(b') * P2(y')) AND (gcd(b',y')==1)

我們成功地把它拆掉了。再轉化一下式子:

我們發現這個gcd很煩,我們用莫比烏斯反演解決:

我們可以預處理最后面那個sigma。前面的復雜度是n^(1/3)*log(n)*log(n)。

TopCoder SRM 583 Div 1 - Problem 950 RandomPaintingOnABoard

期望回合數等於每一回合進行的概率之和。

如果第i回合進行,說明前i-1回合沒有實現每行每列至少一黑。

我們可以行集合和列集合,如果之前每一回合都在這之中選,那么當前回合就會進行。這樣的概率是(sigma x)^(i-1) / S^(i-1) 

由於這樣枚舉可能重復,所以容斥一下即可。根據行集合+列集合的大小的奇偶性來判斷+-符號。

這樣可以算出第i回合進行的概率。

但是對於每一個i,都要計算,這很麻煩。我們發現i只出現在指數上,而枚舉的i是從1到無限大。所以可以用無窮長的等比數列求和公式來計算。

這樣我們得到了一個優秀的2^(n+m)的算法。我們發現數據范圍n*m<=150(很小?) 

我信心滿滿地寫了一個,樣例都Tle了。。

怎么辦呢?我們還漏了一個條件:每個格子上的數是0到9范圍。。

所以我們發現這個公式中底數的范圍只有0到3600,所以有很多項是重復的。對底數進行dp即可。 

TopCoder SRM 584 Div 1 - Problem 900 FoxTheLinguist

我們可以輕松建圖,只要求一個有向圖最小生成樹就可以了。

據說可以用朱劉算法?

我不會啊QAQ

TopCoder SRM 585 Div 1 - Problem 1000 EnclosingTriangle

我們枚舉三角形的一個頂點,如果已知第二個頂點,第三個頂點有一個可行區間。

已知隨着第二個頂點的順時針移動,第三個定點的可行區間是單調的。

再由於只有20個點,所以可以先預處理20個點的凸包,可能還要預處理可行區間左端點的前綴和數組,

可能差不多就做好了吧。。

TopCoder SRM 586 Div 1 - Problem 1000 StringWeight

 顯然,若字符串長L,那么這個輕的字符串滿足有min(26,L)種字符,且相同字符挨在一起。

顯然就可以dp了,f[i][j][k]表示前i個字符串已經完畢,出現j種不同字符,其中有k種字符今后還要再出現,的最小重量。

考慮當前字符串,我們已知了字符種數,

其中有一些連接了之前的字符,並且之后還要出現,它對重量的貢獻是L;

有一些連接了之前的字符,之后不會出現,它對重量的貢獻是前綴長度;

有一些是新出現的字符,但之后不會出現,它對重量的貢獻是它在這個字符串中的長度;

有一些是新出現的字符,之后還要出現,那么它對重量的貢獻是后綴長度。

根據一定的貪心結論,前綴長度越短越好,后綴長度越短越好。那么上述第一種字符和第三種字符一定排在中間。

一個很顯然O(n*26^5)的dp就出來了。

再根據一定的貪心結論,第一種字符變成第二種,同時第三種字符變成第四種,這樣一定更優,

所以復雜度變成O(n*26^4)

TopCoder SRM 587 Div 1 - Problem  900 ThreeColorability

 被題解的做法深深地震撼到了。。

考慮2*2的方格,一定全N或全Z,或兩個N,兩個Z。

推廣到n*m,任意2*2方格滿足這個條件,就一定能被三染色。

分析這個條件,設N=0,Z=1,我們發現相鄰兩行要么完全相同,要么完全相反。相鄰兩列也是一樣。

所以我們可以構造h[i]數組,構造g[i]數組來表示整個能被三染色的矩陣,矩陣中cells[i][j] = h[i] xor g[j]。

任意的h,g數組對應一個合法矩陣。而輸入的'N'或'Z'限制了h[i] xor g[j]的值。

所以可以進行二分圖染色。再因為要字典序最小,所以染色的時候可以貪心。

TopCoder SRM 588 Div 1 - Problem  1100 GameInDarknessDiv1

冷靜分析一下,這道題非常有意思,

考慮現在Alice到達一個點,這個點提根后有多個子樹,且Bob可能存在於這些多個子樹中。

考慮若子樹a大小<=2,那么Alice可以進入a一步,去清除Bob存在於該子樹的可能,然后回到根。

這樣,Bob無法從一個子樹飛往另一個子樹。

而如果子樹a大小>2,Alice進入a會到根至少需要4步,用這段時間Bob可能飛到其他各個子樹中。對Alice極為不利。

所以我們來分析Alice的策略:

只有1個子樹a大小>2:進入a,清除Bob在a的可能性,之后依次清楚其他子樹。

只有2個子樹a、b大小>2:進入a,清除Bob在a的可能性,之后清除除a,除b以外其他子樹,最后清除b。

有3個子樹a、b、c大小>2:涼涼。。Bob無論何時都有可能在兩個大小>2的子樹中。

所以我們得到了Bob的策略,在不被Alice抓到的同時,走到一個節點,使得這個節點提根后有至少3個子樹大小>2

我們也得到了Alice的策略,不讓Bob的計謀得逞。。

所以,當存在一個點 P ,滿足 dis(A,P)>=dis(B,P)+2,且以 P 為根時有至少 3 個子樹的深度大於等於 3 時,Bob 勝,否則 Alice 勝。

TopCoder SRM 589 Div 1 - Problem  900 FlippingBitsDiv1

 按M>sqrt(N)或M<sqrt(N)分情況討論即可。

TopCoder SRM 590 Div 1 - Problem  1000 FoxAndCity

這是道較為有趣的題,

我們發現,a[i]數組合法的充要條件是

a[1]=0,若i>0,則a[i]>0。且如果i,j相連,那么abs(a[i]-a[j])<=1。

有了這個結論之后,我們把每個點都拆成n個點,第k個點和第k+1個點連通表示當前這個點的權值a至少為k。

很容易建出網絡流模型,跑一遍最小割即可。

TopCoder SRM 591 Div 1 - Problem  900 StringPath

一句話題解:輪廓線動態規划(狀壓dp)

TopCoder SRM 592 Div 1 - Problem  1000 SplittingFoxes2

DFT(a) = DFT(p) * DFT(p),已知a,求p。

p = DFT^(-1)( sqrt(DFT(a)) )

由於sqrt的時候,每一項有正負兩種值,需要枚舉。

因為p關於0對稱,所以只要枚舉2^(n/2)種情況即可。

(據說還可以用NTT來排除精度誤差?)

TopCoder SRM 593 Div 1 - Problem  1000 WolfDelaymasterHard

暴力dp是O(n^2)的。很容易發現當右端點為i時,左端點j可行的取值區間只有不超過log(n)段。

這樣很容易實現O(nlogn)復雜度的dp.

題解給了一個優秀的O(n)做法。

我們考慮,如果一個區間的左邊一半全是問號,左端點為i,右端點j可行的取值區間只有一個。

若一個區間左邊一半至少有一個'w',右端點為i,左端點j可行的取值區間也只有一個。

前者從當前dp值對之后一段區間的dp值有貢獻,可以前綴和優化。

后者前面一段區間的dp值對當前dp值有貢獻,也可以前綴和優化。

TopCoder SRM 594 Div 1 - Problem  950 FoxAndAvatar

非常有趣的題哇

很容易發現:答案<=4

又很容易發現,每次取走一塊矩形的時候,對局面有影響的只有兩個值:比x小的數中被取走了多少個數,比x大的數中被取走了多少個數。

我們設比x小的數中被取走了p個,比x大的數中被取走了q個。

很容易證明,p是定值的時候,q越大越好。

所以我們可以進行DFS!

每次DFS,枚舉p的值,O(1)求出當前狀態下,q的最大值。

很容易發現,DFS只要枚舉兩層。在第三層我們O(1)判斷是否可以一次性取完只剩x,否則答案就是4。

復雜度O(n^2)。

TopCoder SRM 595 Div 1 - Problem  900 Constellation

根據經典套路,一個凸包的面積是凸包上相鄰兩個點與原點形成的向量的叉積的和的1/2

只要計算任意兩個點,成為凸包上相鄰兩個點的概率,就可以計算它們對期望答案的貢獻。

即這兩個點所在直線的一側沒有點。

TopCoder SRM 596 Div 1 - Problem  1000 SparseFactorial

若F(x)%m=0,則F(x+m)%m=0

所以我們可以對於所有x%m的余數,求出x至少是多少才滿足F(x)%m=0

先對m分解質因數:m=p1^k1*p2^k2...*pn^kn

求出最小的x,使得x%m=x',F(x)%(pi^ki)=0。(可以對於所有的pi,求出對應的最小x,然后取其max即可。)

存在(x-j^2)%pi=0

存在j^2 %pi = x % pi 

預處理x所對應的可能的j%pi。

所以,我們可以暴力地從小到大枚舉所有可能的j,再求出所對應的比j^2大的x,判斷F(x)分解質因數后是否有ki個pi。

由於ki很小(log級別)!所以復雜度是對的

TopCoder SRM 597 Div 1 - Problem  900 LittleElephantAndBoard

我們考慮,在原來2*M的表格下面,再添一行,變成3*M的表格。

對於每一列,由於相鄰兩個顏色不一樣,我們把第三行的那個格子顏色塗成與前兩行顏色不同的第三種顏色。

由於每種顏色在任意一個2*2矩陣中至少出現了一次,所以第三行中相鄰兩個格子顏色也不同。

以上,題意轉化為了M-R個紅球,M-G個綠球,M-B個藍球排在同一行,相鄰兩個顏色不同的方案數。

緊接着我們發現,相鄰兩個藍球之間,紅綠球必然交替出現。當長度為偶數時,紅綠個數相同。當長度為奇數時紅比綠多一球,或反之。

於是,枚舉長度為奇數的段數,由M-R和M-G可知其中有多少段紅比綠多一。接着就可以直接用組合數計算了。

TopCoder SRM 598 Div 1 - Problem  950 TPS

感覺是很顯然的樹形dp?

如果p的兩個兒子a,b,a,b的子樹內都沒有信標,那么a,b內相同深度的點無法區分。

用這一性質進行樹形dp

TopCoder SRM 599 Div 1 - Problem  950 SimilarNames

我們先把trie樹建出來。要求給trie中字符串結尾的節點標號0到n-1,使得滿足性質。

於是樹形dp的想法就出來了。

然而限制涉及到的點數有8*2=16個,要開2^16的狀態。暴力3^16轉移復雜度不可觀。

注意其實轉移的時候枚舉的很多次子集都是沒有用的。

我們假設dp時要枚舉子集a,枚舉子集b。然后把a、b合並起來。

對於一條限制s是t的前綴,顯然s不能單獨出現在a或b中,同時子集a和子集b不能有交。

對於這一種限制,

a:空, b:空;a:t, b:空;a:空, b:t;a:空, b:{s,t};a:{s,t}, b:空。 有最多5種轉移。

所以總復雜度為5^8*50。(我們需要先預處理這些可能的子集轉移)

 

 ————————————————華麗的分割線—————————————————

 

到此為止,SRM562到SRM599的題就結束了。

再宣傳一下傳送門^_^

https://284914869.github.io/AEoj/index.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM