Chelly我的訓練

###Todolisthtml

arc100F算法


###7.1數組

  • Atcoder Regular Contest 100 <font color="#dd0000" size=5>1/4</font><br />
  • Codeforces #493 div 2 <font color="#00dd00" size=5>4/5</font><br />

###7.2數據結構

  • arc100D:枚舉中間那一刀,而後左邊兩個部分各自均勻切一刀。
  • arc100E:想要求$max(A_i+A_j) (i\ or \ j=k)$,而後根據前綴搞,但這個很困難,沒法求解。考慮求$max(A_i+A_j) (i \ or \ j\subseteq k)$,這個是知足$i \ or \ j <= k$的限制的,能夠用dp搞。
  • cf997C:容斥原理,化簡式子後發現是兩個$\sum$,裏面有兩個組合數形式,能夠考慮枚舉一維,另外一維用二項式定理化簡。

###7.3函數

  • cf997D:樹上長度爲k的環個數計數。
  • cf997E:枚舉右端點,左端點到當前右端點的答案用線段樹維護。因爲問題的特殊性,維護區間最小值和最小值個數。須要維護區間歷史答案和,額外用一個lazy標記就好了。

###7.4優化

  • cf1000F:將詢問按照右端點排序,枚舉右端點r,對於固定的r,用線段樹維護前面每一個位置的pre[i],對於詢問[l,r],就是要找[l,r]中的最小值,固然還有一個suf[i]>r的條件,這個條件只須要每次新來一個r,把pre[r]的位置的權值賦爲inf便可。若是要求在線,那能夠用主席樹。
  • cf1000G:樹dp一下就好。

###7.5code

  • cf995C:有一個結論是任意3個長度<=r的向量,必能夠挑出2個向量經過變換方向組合成一個長度<=r的向量,因此就能夠對原來的一直操做縮小規模,用一個二叉樹來模擬。
  • cf995D:經過概括法能夠得出答案就是全部f的平均數。
  • cf995E:考慮到圖比較隨機,因此實際上步數不會不少(實際上最多40),那就能夠雙向BFS解決了。
  • cf995F:答案是關於D的次數最高爲n的多項式,因此能夠先作一個O(n^2)的dp,而後在D的取值直接插值就行。也能夠dp來處理,咱們關心的只是樹裏面不一樣權值的個數,假設g(x)表示樹裏面權值個數爲x個的時候樹的形態數,那麼總方案數確定是ΣC(D,x)g(x),問題是如何求g。咱們考慮dp[i]表示樹中最大值爲i的方案數(這顯然O(n^2)的DP能夠作出),必定有dp[i]=ΣC(i,j)*g[j],反演求便可。

###7.6htm

  • Wannafly挑戰賽19 <font color="#00dd00" size=5>3/6</font><br />

###7.7blog

  • CodeM2018複賽 <font color="#00dd00" size=5>2/6</font><br />

###7.9排序

  • Wannafly挑戰賽19 D:必定是固定一個迴文子串,而後把一邊砍掉,一邊翻過去一部分,用manacher輔助計算就行。
  • Wannafly挑戰賽19 E:BFS跑出兩個數字之間最少須要多少次變換,而後連邊跑費用流
  • Wannafly挑戰賽19 F:求個前綴和,而後把每一位看做一個26元組,對於一個詢問[l,r]就是問[l,r]裏有多少個pair是相同的,直接莫隊算法就好了。

###7.10

  • CodeM2018 複賽 C:考慮給每一個點賦值0/1,邊權定義爲兩個點的權值的異或。若每條邊都是-1,那麼答案顯然是每一個連通塊點的個數的2次冪乘積。對於已經肯定的那些邊權,先dfs判斷是否有矛盾,如有則輸出0。不然咱們考慮一個由肯定邊組成的連通塊,那麼給定了一個點的確切權,剩下的也已經肯定了,因此把這個連通塊從答案裏除掉就好了。

###7.11

  • CodeM2018 複賽 E:考慮把每個點對抽象成平面上的點,那麼就至關於求矩形面積並。
  • CodeM2018 複賽 D:考慮二分答案,那麼每一個位置就對應了一個區間,咱們把上界作一個凸包,若全部下界都在凸包上面則能夠減小二分的答案,不然要增長二分的答案,但此題能夠有分數,因此二分得不到正確結果。咱們再分析一下二分的過程,發現其實凸包的形狀是同樣的,不一樣的mid只是帶來不一樣的平移量,因此咱們能夠對於最初的點求一個凸包,而後求出點到對應凸包點距離的最大值,把它除以2就是答案。

###7.12

  • CodeM2018 初賽A輪 D:考慮prim算法,從一個關鍵點開始BFS,遇到第一個關鍵點(則這必定是根據prim算法加入進去的邊),而後把這個點的距離設爲0,丟到priority_queue裏繼續擴展。

###7.13

  • Codeforces #497 div 2 <font color="#00dd00" size=5>3/5</font><br />

###7.14

  • Codeforces edu47 <font color="#00dd00" size=5>6/7</font><br />

###7.26

  • Codeforces #499 div 2 <font color="#00dd00" size=5>3/6</font><br />

###7.27

  • CF1011C:修改了下實數二分的寫法

  • CF1011E:把對k取模也加了進去,fix了一下

  • CF1010D:從上往下考慮每一個門,考慮若是當前門的值須要改變,那麼左右兩個孩子哪一個門的值須要改變,就這樣dfs,分狀況討論便可。


###8.17

  • 牛客143B:$x^2-dy^2=k^2$的pell方程瞭解一下。
  • 牛客143H:預處理f(i)表示以i爲開頭的遞增子序列個數,而後逐位肯定。

###8.18

  • 牛客144J:隨機兩個正整數,互質的機率是$\frac{6}{\pi ^2}$,因此咱們能夠把前100大的拿出來跑暴力

###8.19

  • 牛客144I:把區間按照l升序排序,而後用線段樹維護一段的r最大值,根據線段樹去刪除,刪除一個位置的時間是$O(logn)$,因此均攤時間是$O(nlogn)$

###8.20

  • 牛客144G:s和t之間的最小割集必定是一個團和一個孤立點,設$d[i]$表示樹上i點到其它全部點的距離和,那麼$maxflow(s,t)=min(d[s],d[t])$。因而咱們能夠將$d[i]$數組排個序,而後算總貢獻。$d[i]$用樹形dp求便可。

###8.21

  • 牛客144F:在考慮一個點應該放哪一個表達式的時候,咱們只關心lson和rson的值取0/1的狀況數,對於一個肯定的表達式,咱們確定但願一個lson中0/1的數量最多,rson同理,因而咱們令dp[i][0/1]表示第i個點最多能有多少狀況取0,最多能有多少狀況取1,dp[i][0/1]的值必定由dp[lson][0/1]和dp[rson][0/1]轉移過來。這樣作一次樹dp是O(n)的,但注意要使用高精度,由於每一個點的高精度的位數是和子樹大小同階,因此這至關因而一個揹包,因此複雜度是$O(n^2)$的。

  • 牛客144B:傳送門


###8.22

  • 牛客144E:考慮單獨一個字符,至多分裂10秒就可以到達目標串T的長度,咱們先考慮答案<=10秒的狀況。咱們能夠建出T的自動機,而後能夠預處理出f[i][j][k]表示字符i初始從T自動機的k狀態進去,通過j秒的分裂,會從哪一個狀態出來。這樣就能夠輕鬆知道一個字符在10秒內可否搞出T,而後咱們也就知道了初始字符串S可否在10秒內搞出T。接下來考慮答案大於10秒的狀況,咱們從T第一次出現的位置開始回溯,最終必定能夠縮成1個字符或者2個字符(一個提供後綴,一個提供前綴),要注意這2個字符或者1個字符可能不會出如今初始串中,而出如今10s內的生成串中,因此咱們要BFS一遍,求出每一個字符/字符對第一次出現的時間。最後再枚舉字符對便可。

  • 牛客145C:考慮到$3^{18}$並無超時太多,能夠預處理出最後4次的結果。時間複雜度是$O(2^43^4+3^{14})$。


###8.23

  • 牛客145F:考慮枚舉d,算知足mindiff>=d的全部集合的maxdiff的和。還須要枚舉集合裏的元素個數k,一個集合對答案的貢獻是$a_k-a_1$,分開來利用組合數計算。須要知道帶權的楊輝三角對角線的和如何計算。

###8.24

  • 牛客145I:對於一個樹而言直徑有不少但重心只有一個,考慮計算枚舉每一個點做爲重心的答案,顯然考慮可否用點分治。以某個點u爲重心的直徑爲D的樹要怎麼計數呢?首先要知足至少有兩個離它深度爲D/2的點分佈在不一樣的子樹,而後剩下深度<D/2的點隨便取不取。這樣咱們須要維護兩個東西,一個是<D/2的點的總數,一個是從某個分支出發,有多少個深度剛好是D/2的點,這個用一個map便可。注意到D要討論奇數和偶數狀況很複雜,能夠考慮在原樹中的每條邊之間添加上額外的點,那麼就只要統計偶直徑就好了。時間複雜度$O(n\log n)$。

###8.25

  • 牛客146H:將問題轉換成,最少選取多少個數字使得它們的異或值爲給定值x。最多隻要選取20個,咱們能夠考慮dp[i][x]表示至多選i個數字可否湊成數字x。那麼每步轉移就是給異或卷積,能夠用FWT優化。在每次循環裏,實際上只是關心一個位置x的點值是否爲0,咱們能夠利用FWT(A)函數的定義來$O(n)$求解,因此時間複雜度是$O(x \log x)$的。

###8.26

  • 牛客146B:對於一個合法方案,必定能夠分紅$n_1+n_2$的形式,即左下角一個$n_1$方陣,右上角一個$n_2$方陣,或者左上角一個$n_1$方陣,右下角一個$n_2$方陣。咱們稱前面爲A類,後面爲B類,顯然A類和B類的數量是一致的。咱們設$g(i)$表示$i \times i$的方陣,有多少個A類方案,$f(i)$表示$i \times i$的方陣總方案是多少。顯然有$f(1)=g(1)=1,f(i)=2g(i) \ (i>=2)$。考慮遞推求解$g(i)$,對於一個A類方案,咱們必定能夠找到一個最小的$n_1$,使得每一個方案只被統計一次。那麼有$g(n)=\sum_{i=1}^{n-1} g(i) \times f(n-i)$,繼續化簡有$f(n)=f(n-1)+\sum_{i=1}^{n-1} f(i) \times f(n-i)$。這個用cdq分治+NTT處理便可。

  • 牛客146C:能夠用樹形DP求出以點u做爲根的子樹向下的貢獻,以點u向上的貢獻。而後再用樹形DP統計出以u爲根的連通塊的總貢獻。題解給出了一個更妙的思路,考慮枚舉路徑集合,算有多少連通塊知足要求,容易發現若固定一個路徑集合,那麼知足條件的連通塊必定就是路經集合分割而成的連通塊數量,這個等於白點數-兩端都是白點的邊數。因而能夠兩部分分開計數,前者就是至關於統計不通過某個點的路徑集合數量,後者是統計不通過某條邊的兩個點的路徑集合的數量,均可以樹形DP完成。


###8.27

  • 牛客146I:找到第一個不同的最高位pos,把數字分紅兩個集合A和B。A中數字pos位爲0,B中數字pos位爲1。顯然咱們能夠利用01Trie獲得答案ans,接下來主要考慮方案的選擇。咱們能夠把這些數字當作一個二分圖,左邊點集互相有邊相連,右邊點集互相有邊相連,而後對於那些異或結果是ans的點對,咱們從A向B連一條邊,咱們須要找的就是一個字典序最小的哈密頓路。咱們能夠貪心的從高到低逐位肯定,假設上次選擇的點是u,它所在的集合在c。那麼接下來咱們要麼在c集合裏找一個點,要麼在u相連的另外一個集合的點裏尋找一個點,這些均可以用數據結構來維護。具體來講,用set維護點集中剩餘的點,用mpa<int,priority_queue>維護一個點相連的另外一個集合裏的點。

  • 牛客146J:固定一個n,那麼生成函數就是$(1+x)^n$,因此原問題的生成函數就是$F(x)=(1+x)^0+(1+x)^2+(1+x)^4+...=\frac{(x+1)^{n+2}-1}{(x+1)^2-1}$,咱們所要求的就是$\sum_{i=0}^{m} [i=0 \mod 2] [x^i] F(x)$。把F(x)化簡一下,能夠獲得$F(x) \times (x+2)=\sum_{i=0}^{n-1}\binom{n}{i+1}x^i$。設F(x)裏$x^i$前的係數是$b_i$根據這個式子,咱們能夠發現$b_0和b_{n-2}$是肯定的,其他的$b_i$能夠由$b_{i-1}$或者$b_{i+1}$遞推獲得。那顯然咱們遞推出前M項,問題就解決了。但關鍵是是模數是偶數的時候,可能會致使遞推式子裏的$\frac{1}{2}$沒有逆元。咱們能夠這樣來,將$mod=s \times 2^t$,分別求出模s和模$2^t$的值,而後CRT合併起來。s必定和2互質,因此必定就有逆元了,能夠遞推了。關鍵就是如何求模$2^t$的結果。考慮倒推,有$b_i=\sum_{j>=i+2} (-2)^{j-(i+2)}a_j$,當$j-(i+2)>=t$ 的時候,顯然貢獻爲0,因此這個j頂多枚舉t項。整個時間複雜度是$O(m \log mod)$的。這個問題須要會在$O(n \log mod)$的時間內求出$\binom{m}{0},\binom{m}{1},...,\binom{m}{n}$。


###8.30

  • hdu6064:BEST theorem定理的應用。注意這裏是固定了起點,因此歐拉回路的數目須要乘上$deg(1)$。同時,這裏將重邊看做相同的了,因此方案要除以每一個重邊的數目的階乘。

###9.7

  • Codeforces Edu 50 <font color="#00dd00" size=5>4/7</font><br />

###9.9

  • CF1036F:莫比烏斯反演。比較坑的地方在於求i次方根若是直接用$pow$精度會不夠,須要對於$i=3~60$的先預處理打表,詢問在其中二分。

###9.13

  • hdu6356:將ST表倒過來。

  • hdu6357:考慮反轉值域,01...xy(y-1)....xy*(y+1)...9,而後dp匹配模式串。


##9.14

  • hdu6352:分圓多項式用來因式分解。

###9.17

  • hdu6353:點分樹。對於點分樹上每個節點u,維護點分治過程當中u對應的那坨樹到u的距離關係,而後求個前綴和。對於一個詢問,在點分樹上暴力爬就行,但注意要對答案容斥,因此還須要維護點分治過程當中u對應的那坨樹到last[u]的距離關係。(last[u]是點分樹上u的父親節點)

###9.18

  • hdu6360:旋轉規則參照正十二面體,能夠列出四種置換羣對應的置換個數,根據對稱性算出循環個數。而後dp[i][j]表示用了前i個顏色塗了前j個循環的方案數,轉移就枚舉第i種顏色塗幾個循環便可。

###9.24

  • Codevs 3160:廣義後綴自動機。統計每一個點表示字符串在哪些字符串裏出現過。

  • bzoj3238:後綴樹。先考慮利用SAM建出後綴樹,對於兩個end節點,它們的lcp就是後綴樹上的lca的深度(也就是lca的maxlen)。因而咱們能夠考慮樹形DP,枚舉每一個樹上點做爲lca,統計這種狀況下的答案。


###9.25

  • bzoj3998:經典問題,利用SAM求第k小子串。考慮先拓撲一下,把SAM上每一個節點向後能走出多少個子串求出來,而後就是從0節點開始從小到大嘗試分支。

  • bzoj3676:迴文樹模板題。

  • bzoj4199:建出後綴樹後樹dp便可,注意權值有負數,因此記錄子樹內最大和最小值。

  • bzoj4310:考慮先二分一個mid,將字典序第mid小的字符串做爲答案(能夠用SA或者SAM),而後來斷定是否可行。注意到分紅的那些段中,字典序最大的必定是某個後綴,因此咱們能夠從後向前貪心,每次新加一個位置i就是新加一個 後綴,主要就是比較這個後綴與咱們第mid小的字符串的大小關係。這個能夠利用後綴數組求出它們的lcp來輔助判斷。

  • bzoj4566:廣義後綴自動機模板題。固然你須要正確地建出廣義後綴自動機。


###9.29

  • bzoj2780:創建廣義後綴自動機。在創建第i個單詞的過程當中,若是新建了一個節點z,那麼從z開始跳parent鏈,給鏈上的節點都賦上當前單詞的顏色,最後對於每一個詢問就至關於統計自動機上某個點被染顏色的個數。能夠用id[u]表示當前節點被染的顏色來輔助求解,能夠感性理解一下,這個時間複雜度很對……

  • ARC103C:奇偶分開求出現顏色的最多和次多,最後討論一下便可。

  • ARC103D(small case):容易發現詢問點與原點的曼哈頓距離必須奇偶性都相同,而後只須要定每條機械臂長度爲1就能夠搞一搞了。

  • ARC103E:如有解,必需要知足:S[i]=S[n-i],S[1]=1,S[n]=0,而後根據S序列,在以前的節點基礎上創建一個父親,用額外的單點來填充size,構造樹便可。


###10.1

  • bzoj3277:相似bzoj2780,建出後綴自動機,求出每一個點表示的子串在多少個字符串中出現。該問題要求相同的字符串不一樣位置算多個,最容易想到的就是求出全部點在每一個顏色的下的endpos,但這樣時間複雜度十分爆炸。把每一個串做爲一個詢問串,考慮其每一個前綴i有多少個後綴是知足條件的,這等價於先找出在後綴自動機上該串前綴i的終結節點,而後跳parent鏈,看有多少個節點的cnt>=k。這樣時間複雜度也是不對的。因此能夠先按照拓撲序dp一下,獲得每一個點到root的鏈上的點的權值和,這樣複雜度就是線性的了。

  • bzoj3926:注意到葉子節點個數<=20,那麼把每一個葉子節點提起來做爲根,獲得就是一個Trie。因此本質上就是把這20個Trie對應的廣義後綴自動機建出來就好了。

  • bzoj2806:先二分一個L,而後能夠dp求出最長匹配多少位置。$dp(i)$表示前面i個位置最長能被匹配多少,那麼有$dp(i)=max(dp(j)+i-j) i-j>=L 且 s[j..i]是某個子串$,咱們能夠提早預處理出mx[i]表示s[1..i]中最長的做爲子串出現的後綴,而後就是一個單調隊列優化DP。至於怎麼求這個mx[i],就是從前日後一直匹配維護一個cur,表示當前s[1..i]的最長後綴的長度爲cur,若是從當前自動機節點有一個s[i+1]的轉移,那麼就轉移過去而且cur+=1,不然就順着slink跳直到有這樣的轉移的節點u',cur=maxlen[u']+1。

  • HackerRank special-substrings:先把問題變成「一個字符串有多少個本質不一樣的子串能夠做爲它迴文子串的前綴」。咱們能夠先建出後綴自動機,而後對於每一個本質不一樣的迴文子串在自動機上更新答案。具體的,用迴文樹跑出以節點i爲後綴的新增迴文串,設其爲s[j..i],長度爲len,那麼咱們從表明後綴S[j]的後綴自動機節點u開始,一直向上跳slink鏈,若某個點maxlen<=len,那麼這個點能夠被徹底覆蓋,若是minlen<=len<=maxlen,則部分覆蓋,固然直接跳鏈會T,能夠考慮倍增跳。由於這裏是離線,因此跳的時候就要注意答案的更新。時間複雜度$O(nlogn)$。

  • bzoj1396:首先跑後綴自動機,挑出那些出現一次的位置,記下該點的suf。設點u對應的字符串出現1次,u點表示的終結位置是i,那麼有[i-minlen[u]+1,i]以內對i-minlen[u]+1取min,[i-maxlen[i]+1,i-minlen[i]+1]以內對i-j+1取min,用兩個線段樹打標記便可。

  • bzoj4516:字符集比較大,用map便可。

  • hihocoder 1466:建兩個後綴自動機,跑出sg函數。而後就是個逐步肯定問題了,這裏要涉及到兩個的逐步肯定,寫的十分自閉。

  • hihocoder 1465:很容易想到把詢問串T接一下,而後求每一個前綴i的最大出現後綴,找到以i爲後綴的包含長度n的節點u(須要跳slink),而後給這個節點打上標記。注意可能會出現循環同構,因此若是某個節點以前被打上了標記,那麼此次就不累加結果。


###10.2

  • ARC103D(big case):容易發現,當全部$x_i+y_i$的奇偶性同樣時,就有解。特別的咱們假設$x_i+y_i$是奇數(如果偶數,能夠先讓他們朝一個方向都走1)。而後,咱們將機械臂長度定爲2的次冪,就能夠構造出全部解了。具體的構造方法就是每次把當前的1填到長度爲奇數的地方,而後給座標除以2,不斷進行下去。

  • ARC103F:值最大的點必定是葉子,值最小的點必定是重心,咱們不妨把最小的點(重心)看成根,去構造有根樹。那麼顯然從根往下知足D值單增。因而咱們能夠先對全部D排序,就獲得了拓撲序,而後從下到上考慮每一個點的父親應該是誰。利用D[u]=D[v]+2*sz[v]-n來對於一個v找其父親便可。


###10.12

  • SPOJ DIVCNTK:直接min25篩。

  • SPOJ APS2:雖然不是積性函數,但比較特殊,也能夠套用min25篩的方法作。

  • bzoj 4916:是積性函數,直接min25篩。


###10.21

  • CF #517 div 2:<font color="#00dd00" size=5>4/6</font><br />

###10.25

  • CF edu 53:<font color="#00dd00" size=5>4/7</font><br />

###10.26

  • CF1073E:直接數位DP

###11.1

  • 牛客215F: 用kdtree維護每一個點左下方點的個數a,左邊點的個數b,右上角點的個數c

###11.13

  • CF1076F:$dp[i][0/1]$表示作了前i段,最後以0/1結尾的最短長度,而後對於新的一段,貪心去轉移

###11.30

  • CF1082G:若選擇一條邊,那麼它兩個端點都要選取,因而能夠將全部的邊看成點,因而問題變成了最大權閉合子圖問題。

###12.2

  • 牛客296B:首先通過簡單分析將問題變成了給定一些區間,容許有區間覆蓋但不容許區間交,問給定的這些區間是否合法。將全部區間按照左端點升序排序,而後用單調棧維護一個右端點遞減的嵌套區間。
相關文章
相關標籤/搜索