Codeforces Round #219 (Div. 1)(完全)

戳我看題目

A:給你n個數,要求儘可能多的找出匹配,如果兩個數匹配,則ai*2 <= aj

排序,從中間切斷,分成相等的兩半後,對於較大的那一半,從大到小遍歷,對於每個數在左邊那組找到最大的滿足條件的數配對

用一個變量移動一下就好了。這樣的配對數量肯定就是最多的。

因爲

1:如果左邊那一半數量取少一點,比如取a1 a2 a3...ak (k < n/2)

那實際上ak+1 ak+2 .. a n/2 這些數就沒啥用了,因爲後面那一半數已經足夠匹配當前的這些數了,不可能後面還有某些數不匹配而拿這部分數來匹配

2:如果左邊那一半數量取大一點,那後邊那一部分的數量就小於一半了,這時候最多就只能匹配後面的數的數量了,那還不如把左邊多餘的那部分去掉呢

所以最優的答案肯定是分在中間的。


B:40*40的01矩陣,很多個詢問,問某個子矩形內有多少個全0矩陣

預處理O(n^5),O(1)回答

f[a][b][c][d] = f[a][b][c-1][d] + f[a][b][c][d-1] - f[a][b][c-1][d-1]+sum;

sum是包含右下角那個0的矩形的個數,這個只需要再O(n)掃一遍即可得出


C:給你m<=300個煙花的燃放時間與地點,還有一個價值,燃放的位置是1~n(n <= 150000);,如果煙花燃放的時候人在某個位置,就能

獲得 bi - |ai - x|的價值,也就是價值減去位置的絕對值之差,最後問觀賞完所有的煙花後最大獲得的價值是多大

dp[i][j]表示前i個時刻停留的j位置的最大價值。然後能夠從dp[i-1][k]轉移過來,稍微觀察


一下就發現k跟j的距離是<=len(len爲定長)


然後就用單調隊列維護一下定長區間的最大值掃描兩遍就好了


D:在一棵樹中找一個大小<=k的聯通塊,使得這個聯通塊中出現的最長連續的區間最大


不知道那個dfs序的性質這個題還真是難做啊。。


維護two pointers,題目就轉換成判斷包含LR區間的數的聯通塊的點的最小個數,可以將


這些數按照dfs序排序後,相鄰兩個點到lca的距離加起來,然後,第一個點與最後一個點


到lca的距離加起來,這時候發現最小的聯通塊的每條邊都被加了兩次,然後就可以求點


數了。

具體實現的時候用一個set維護一下就好了,細節處理的不好會很當疼,不過對於神牛來


說總是有很好的方法可以搞定,看CLJ代碼就知道了。。。


E:平面上有n個點,問你有多少個這樣的點的集合 (P1, P2), (P3, P4), ..., (P2k - 1, P2k)

  • For any two pairs (P2i - 1, P2i) and (P2j - 1, P2j), the circumcircles of triangles OP2i - 1P2j - 1 and OP2iP2j have a single common point, and the circumcircle of triangles OP2i - 1P2j and OP2iP2j - 1 have a single common point.

就是在這個集合裏任取兩對點,(a , b) (c , d),  三角形Oac的外接圓與三角形Obd的外接圓有一個公共點,三角形Oab 與三角形Ocd的外接圓有一個公共點

反演:http://zh.wikipedia.org/zh-cn/%E5%8F%8D%E6%BC%94

反演是種幾何變換。給定點O、常數k,點P的變換對應點就是在以O開始的射線OP上的一點 P'使得|OP||OP' | = k2

反演的結果:

  • O直線:直線
  • O:不過O的直線
  • 不過O的圓:圓
  • O的球:不過O的平面

對於點x=(x_1,x_2,...,x_n),以原點爲中心,在直角座標系的反演變換可寫成

x_i\rightarrow \frac{k^2 x_i}{\sum_j x_j^2}

反演中心爲O,過O的圓對O的反演就是一條不過O的直線,現在兩個圓只相交於O點

,反演之後的兩條直線也應該相交於O點的反演點O*,而O*位於無窮遠處,所以兩直

線平行,所以兩個圓只有一個交點這件事情就可以轉換成a b c d構成一個平行四邊形

。。下面的事情就簡單了。反演後對中點哈希即可。

https://github.com/becauseofyou/Contests/tree/master/Codeforces/CF_219div1

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章