鱼的记忆[较为重要的知识点/技巧]
傳說中魚只有7s的記憶。 
 而我不足7s的記憶。 
 真是悲傷TAT 
 記了什么東西,一會就忘記了。
我當時初中的時候想去自學高中課程…… 
 但是自己完全沒看懂。 
 其實不是自己看不懂而是自己“覺得”這個東西沒什么用。 
 而且還”難”。 
 所以就選擇性的忘記了。 
 我不想我學過的SAM,LCT什么的都變成選擇性忘記的東西。 
 真的決定,要么一個東西完成100%. 
 要么就一點都不要碰。
在此總結一些OI上的容易”忘記”的知識點: 
 以下雖然有標號,但是感覺是不分先后的。
1.單調性
掃左端點右端點單調。 
 習題: 
 1.n個正整數,m個區間,選k個使得交區間的和最大。 
 注意到,按照左端點排好序之后,掃描左端點的時候,右端點是單調不降的。 
 實際上,右端點是右側數第k個。 
 那么開個線段樹隨便做。
2.容斥原理
容斥原理似乎很容易解決一些問題: 
 1.交集轉并集的補集。 
 大大走格子: 
 n*m的格子,有些點(1k)不能走,只能走右下,求方案數。 
 首先注意到任意走的話,可以寫成組合數的形式。 
 那么我們容斥的話就要減掉所有的不合法的方案數。 
 注意到,如果第一個障礙不相同,那么其他就不相同了。 
 而只要踩了一個障礙,那么怎么走都不合法。 
 這樣這個題就能解決了。 
 2.硬幣購物(放個板子題) 
 3.HDU5731(插頭DP+容斥)
3.分塊思想
有一些東西,我們可以根號大暴力。 
 比如說51nod的三個題: 
 1.求整數n的不同劃分方案數,一個劃分中不能有相同的數字。 
 對n分類:>sqrt(n)只能選根號個,小于根號的也不會超過500。 
 f[i][j]表示湊i用了j個數字。 
 那么我們會發現實際上是在集合里填數的過程,即要么集合整體+1,要么加入一個新數再整體+1. 
 隨便算。 
 2.求整數n的不同劃分方案數,一個劃分中可以有相同的數字。 
 對>sqrt(n)是可以用第一題的方法解決的,但是小于的話我們好像不太好解決。然而可以背包。 
 那么我們合并一下就完了。(注意大于的時候要設一個單位元) 
 3.你有n元錢。去買東西的時候,價格為i的恰有i個。正好花完這n元的方案數是多少? 
 如果>sqrt(n),那么我們就是依舊的第二題。 
 小于的話顯然可以多重背包,但是會發現T掉了。(廢話) 
 仔細看看就是個模意義下的前綴和? 
 解決了。。。 
 2016-11-21 
 Codeforces #380 div1.D 
 雖然注意到根號,但是完全不覺得有用,這就是死因所在。 
 我們一定要注意到奇特的地方,然后試圖去解決它。
4.黑科技建圖
我記得有個人的博客上寫了這一坨東西,大概是一個可持久化線段樹優化建圖的事情,具體題目在BZOJ的某個題有個”XXXXXXII”這個題面應該很好找。 
 PA2011 Journey 
 首先我們發現暴力建圖不可取。 
 然后如果想一想的話,實際上可以把這個連續的一段點拆成區間。 
 那么我們考慮用某個點P去更新答案的時候,只需要看P所在的這段區間是否被之前的子節點更新過了就行,因為這是bfs的過程。 
 我們發現每個區間必然只會更新一次,每個點必然也只會被更新一次。 
 那么總復雜度是O(跑得過)。
5.前綴和
不會前綴和的人在BJOI都被6題暴力了。 
1.BJOI的SBD1T3。 
2.n個數,問所有區間中多少個區間平均值>=m。 
我們來看這個題。 
首先顯然的轉前綴和,這樣變成了s[r] - s[l - 1] >= len * m 
不行,還不能做。 
實際上,我們關于這個長度的定值,顯然也是可前綴和的! 
s[i] = s[i] - i * m; 
這樣的話我們就問有多少s[r] - s[l - 1] > 0。 
離散化之后,枚舉左端點,右端點在樹狀數組中查詢。
6.離線算法
許多人啊。 
他們不知道離線的可貴。 
他們不知道只有刪除的題可以離線轉成只插入的題。 
嗯沒錯我就是他們中的一員。 
1.每次刪除一條邊,詢問聯通塊個數。 
離線+并查集。 
2.莫隊的題。 
3.暴力分塊重構。 
4.覆蓋問題(顯然每個點只需要倒著覆蓋一次即可) 
……
7.倒著DP
習題1.獎勵關。 
習題2.hzwer的模擬賽有一個很好玩的題。
8.數值的定義域
這個是什么呢…… 
就是有個顯然的把所有數值都存起來的題,然而我沒想出來。 
在做一些明顯有最大值最小的東西,然而還讓你變成最簡分數的題的時候,可以看看它的數值的定義域,是不是可以承受的級別。 
為什么要墨跡這么多呢,因為我記不得題面了。
9.最短路
我SPFA寫拆點的題就沒有一次能想到拆點啊摔
10.要學會解方程
這里的意思是,解一個方程的過程要寫出來。 
比如ax+by=e
你并不知道 a,b,c,d是否是正整數,所以這樣會很麻煩。
干脆寫個高斯消元?
并不知道這種東西怎么考慮。
11.用堆維護刪除序列
習題:鏈表+堆維護最大M子段和。
12.雙指針
習題1:n只寵物小精靈一共有m種,你要每種至少抓一只,只能抓連續一段小精靈,求最小的區間長度。 
 注意這個轉移指針是O(1)的。 
 //好像如果能用雙指針轉移往往都是O(1)的啊 
 //一般來講前綴和+二分可以變成雙指針的形式。
13.常見貪心:
用大的帶小的:乘船問題什么的。 
 每次合并兩個小的:合并果子。 
 balabala
14.暴力DP:
暴力DP的想法雖然大家都懂,就是先列一下樸素的方程,然后再說別的。 
 但是顯然對于這個題…… 
 真的是想一想暴力就A了啊GG 
  
 考慮f[i][j][k]表示sum為k,走到(i,j)。 
 然后沒了。
15.CDQ分治:
作為一個能寫動態開點線段樹就懶得寫別的的時候。 
 被卡空間的時候真是喜聞樂見。 
 神TM不會CDQ分治啊…… 
 以后能用CDQ就不寫數據結構了! 
 代碼能力–; 
 => 代碼能力 < 0.
16.卡特蘭數
卡特蘭數f(n)是長度為2n合法括號序列方案數。 
 其計算公式
推導過程(ノ*・ω・)ノ
首先肯定是在 2m+1位上 第一次出現了右括號(記作0).
對于剩下的 (n?m)個1以及 (n?m?1)個0所能任意組成的序列個數,等價于 (n?m)個0以及 (n?m?1)個1所能任意組成的序列個數.
那么實際上,對于所有的m,我們都計算一遍。
不過仔細想一想,實際上就是詢問長度為 2n序列中,有 n+1個0的序列個數。
得證。
17.法里級數
我們如果要得到以m為分母的所有的真分數,那么肯定是: 
 (1..i) / m 
 但是肯定有一些東西不是最簡分數。 
 我們知道,化簡之后肯定是一個p/q的形式。 
 那么我們把它都化簡之后,對于分母q能得到:p/q,(p,q)=1 
 我們知道,對于所有化簡之后的分母,我們能得到m個最簡分數。這樣,我們推斷出一條性質: 
∑d|nφ(d)=n 
 估計這個很好玩,可以出題。
18.暴力建圖的優化
河里有n個點,每個點上可以放m種盤子,每種盤子有代價。 
 現在問你在點上放盤子走到對岸的最小代價。 
 我們顯然能看出這是個最短路題,但是我們暴力拆點建圖的話,點數是O(nm)的,但是邊數爆炸。 
 我們可以仔細考慮一下,實際上我們只需要對于點i的對應著第j個盤子向第j+1個盤子連代價差就行了。然后對于每個點,我們自己連自己的價格差就行,這樣邊數就降低到了O(n2m).
19.刪除一類問題的單調性/永久性
bzoj 3069 可以發現,每個邊雙在刪除最后一條邊的時候,才會被永久消除。我們倒過來插入,啟發式合并即可。但是由于自己太懶了,寫的LCT。 
 [PA2011]Journey 考慮到一個點如果被遍歷到了,實際上它就被永久刪除了,那么我們開個set什么的記錄一下,或者用鏈表刪掉它即可。
20.掃描線
掃描線和預處理不同,掃描線是你邊加入貢獻邊算答案,你并不知道未來/歷史的值,而預處理就是你知道過程中的所有的值。 
 我們來看SRM671的Div1600的題目: 
 給你一個序列s,問滿足a<b<c<d且ac=bd的四元組個數。序列長度小于等于1000. 
 如果我們采取預處理的辦法,是沒辦法得到答案的,因為我們要記錄每一時刻的答案。那么不妨倒著枚舉b,然后加入所有的(c,d)元組,再枚舉a來更新答案。
似乎四元組的常見思路是想辦法枚舉中間兩個/把前兩個和后兩個獨立開來。 
 詢問[l,r]的數值個數。 
 [i,last[val[i]]]看作一個點,然后我們就需要知道橫坐標在[l,r],縱坐標[0,l-1]的矩形點數。 
 這個顯然可以1個log解決。 
 離線:掃描線 
 在線:可持久化
21.鴿巢原理
CF681A 
 構造題,題意:構造一個長度為n的序列,使得這m個區間的mex值的最小值最大。 
 做法:如果考慮鴿巢原理的話,我們每1..len就順序放排列,這樣的話顯然的一件事情就是對于長度大于len的肯定能滿足條件。這就是鴿巢原理的應用。
22.查詢區間的小于一個數值的個數
這個顯然是主席樹/掃描線+樹狀數組。 
 題目: 
 一個n個節點的樹,m次詢問,每次詢問一個點u滿足dep[u] + val[u] >= dep[v]的v的個數。 
 顯然對dfs序建樹然后搞一搞就行了。
23.環<=>二分圖(注意特殊的度數情況)
環=>入度等于出度。 
 那么意味著一個匹配。 
 BZOJ3171 
 直接建圖跑費用流即可。
24.寫遞推式
無論什么時候,都不要忘記寫遞推式。 
 無論你覺得那個遞推式難不難寫。 
 收智商稅的時候到了: 
 SRM664D1L1: 
 兩堆石子。每次從大的里撈出小的那部分,然后放到小的石子那堆里。 
 問k次操作時候會變成啥樣。(int范圍) 
 交智商稅的時間到了! 
 叫你不寫遞推! 
 叫你不寫遞推! 
 叫你不寫遞推! 
 叫你不寫遞推! 
 叫你不寫遞推! 
 叫你不寫遞推! 
 令f[i]表示第i次的最小的那堆的數目。 
f[i]=2?f[i?1]<SUM?(2?f[i?1]):(2?f[i?1]?SUM) 
 快速冪解決即可。
25.點分治
點分治是解決樹上路徑問題的比較常用的做法。 
 我們解決點分治的時候,如果處理要過x的路徑,那么通常會面臨算到了x的某個子樹里面去這種問題。所以我們通用的一種做法是先計算答案,然后再Update一下這個子樹的貢獻。 
 還有一種想法是容斥,比如點分治的板子題,我們就用了容斥的思想,先什么都不管暴力算一算,不管在不在子樹里面,然后直接把子樹的這種暴力的答案減掉就行了。
26.樹思想
之前自己只知道一棵叫做dfs/bfs樹的東西。 
 現在知道了很多恐怖的東西。 
 比如點分樹(solve(x)調用的時候形成的樹),fail樹(AC自動機的那個fail指針的樹)。 
 很多東西需要自己發現,而不是別人說:”告訴你,點分治形成了個樹”的時候,你才知道點分治會搞出個樹。
27.線段樹分治
我不得不說似乎這個東西挺妙的。 
 把插入刪除變成只有插入和撤銷兩種操作,還是挺好玩的。 
 另外還學到了并查集的啟發式合并,感覺非常開心。
28.歐拉定理
在b>φ(p)的前提下: 
 
29.平方與卷積
(a?b)2=(b?a)2. 
 那如果在前面乘上一個f(a),就成卷積形式了,就可以FFT了!
30.斜率優化
其實是個很簡單的東西,把i和j分離,把只和j有關的看作Yj,然后把i,j都有的那個j那項看作橫坐標,用i那項去碰凸殼就行了。
31.極差的性質:
一段區間的子區間極差最大值: 
 顯然等于這段區間的極差。 
 因為增長區間之后,最大值不降最小值不增,故極差不降。 
 一段區間的子區間極差最小值: 
 顯然等于每個相鄰兩個數的差值,理由是極差不降。 
 來自北京冬令營的T3。
總結
以上是生活随笔為你收集整理的鱼的记忆[较为重要的知识点/技巧]的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: C语言标准库中round函数
- 下一篇: 学不会编程?试试我的方法
