知識點整理
• 獨立事件:互相不影響的事件,滿足
• 對於獨立事件,我們有
•
•
•
• 期望的線性性:
• 對於離散變量 X,
• 1. 有 n 個隨機變量 ,每個隨機變量都是從 中 隨機一個整數,求 的期望
• 2. 概率爲 p 的事件期望 次後發生
總結
在做和期望有關的題目時,總體思路我覺得和dp很像,考慮事件的所有情況,並考慮相應的計算方法。通過對隨機變量巧妙的定義達到解題的的效果。
要謹慎考慮每種事件發生的概率,概率均等是重要的條件。
要謹慎判斷一個事件是否是獨立事件,不要想當然。對於 和 這兩個特性要在確定爲獨立事件後使用
小技巧 : 通過這樣轉化後再整理式子有時會有奇效
知識點整理
分治:
主要思想是通過將區間分成兩個區間,來將問題分成兩個子問題,大事化小
二分
二分就是對答案分治
重點是怎麼快速的check
整體二分
把答案和修改操作一起二分,通過處理子問題的順序來保證處理答案時的正確性
CDQ分治
把 [L,R] 分成 [L,mid] 和 [mid+1,R],考慮左邊對右邊的貢獻。
好處在於在面對題目時通常可以將形似的約束略去
點分治
其實就是樹上分治?
選擇重心作爲根是常見的小策略,然後對每一個子樹進行分治。
因爲重心保證每一棵子樹的大小 因此可以保證時間複雜度
時間分治
老師只講了一句話:就是對時間進行分治?(霧)
圖論:
(感覺圖論偏簡單?)
BFS
BFS染色,很多後面的題目都要用的東西
遇到邊權只有1或2的時候把邊權爲二的邊拆邊
Dijkstra
原理:當前 d[x] 最小的 x 一定已經確定了最短路
不能處理負權
堆優化可以到
SPFA
隊列優化的Bellman-Ford
用一個隊列維護有哪些點等待更新
每次取出一個點 x 去更新所有出邊 (x,y,w),如果 y 被更新了就壓入隊列
時間複雜度:
菊花圖秒卡。。
(關於SPFA,它已經死了)
用處:
判負環:
判斷最短路的邊數是否>n
判斷一個點是否入隊超過 n 次
原理爲加入超過n條邊必然有負環
差分約束:
對於 (x,y,w),d[y]<=d[x]+w
最短路問題可以給出這一類不等式的最大解(最小解)
(用SPFA是因爲Dijkstrla不能有負權)
Floyd
最穩定的算法
可以算任意兩點最短路
原理是基於dp的:
表示 到 的路徑中,滿足路路徑上的點的標號 都不超過 的最短路徑。
次短路
一條次短路一定至多經過一條非最短路圖上的邊
先跑兩邊單源最短路(頭一遍,尾一遍),然後處理非最短路圖上的邊
最短路變種
每次刪一個點後詢問最短路
每次刪一條邊後詢問最短路
總體思路和次短路差不多
Prufer序
可以一一對應的把一棵樹變成一個序列
每次選擇樹上標號最小的葉子,刪掉它,將與它相連的那個點的標號加到序列里,直到只剩下2個點
由此得:n 個點的無根樹個數爲
Tarjan
(我發現我快不會寫Tarjan了)
(然而老師上課還跳了)
對整個圖進行 dfs,設dfn[x] 表示點 x 是第幾個被搜到的
low[x] 表示 x 通過非返祖邊,且至多通過一條非樹邊能到達的最小dfn
用處:求割點割邊,強連通分量
複雜度:
歐拉回路
定義:一張有向圖,一條經過每條邊恰好一次的回路
(哈密爾頓迴路是經過每個點一次)
必要條件:
1.這張圖是個強連通分量
2.每個點的出度等於入度
3.可以發現這兩個條件同時也是充分的
(充分即有這兩個條件,則必有歐拉回路)
二分圖
可以分成兩部分,使得這兩部分內部沒有邊的圖
一個圖是二分圖則圖內無奇環
判奇環:BFS染色
判偶環:若兩個奇環有一條邊,則存在偶環
最小頂點覆蓋:選最少的點覆蓋所有邊
|二分圖最小頂點覆蓋|=|二分圖最大匹配|
最大獨立集:選最多的點使得它們兩兩沒邊相連
|二分圖最大獨立集|=總點數-|二分圖最小頂點覆蓋|
(關於二分圖匹配,請右轉百度 匈牙利算法 or dinic)
(搬課件一時爽)
Hall定理:
設 是左邊點的一個子集(二分圖將點分成兩邊),設 爲 所有點鄰居的並集,則一個二分圖存在完美匹配的充要條件是:對於所有 ,
字符串:
(SA,SAM是真的毒瘤!)
Hash
課件上老師打了歎號!然後跳了?
KMP
(又一個快不會寫的東西)
KMP是利用之前已經部分匹配這個有效信息,讓模式串儘量地移動到有效的位置。
設 next 數組爲除當前字符外的最長相同前綴後綴
其算法流程如下:
假設現在文本串S匹配到 i 位置,模式串P匹配到 j 位置
如果j = -1,或者當前字符匹配成功(即S[i] == P[j]),都令i++,j++,繼續匹配下一個字符;
如果j != -1,且當前字符匹配失敗(即S[i] != P[j]),則令 i 不變,j = next[j]。此舉意味着失配時,模式串P相對於文本串S向右移動了j - next [j] 位。
換言之,當匹配失敗時,模式串向右移動的位數爲:失配字符所在位置 - 失配字符對應的next 值,即移動的實際位數爲:j - next[j],且此值大於等於1
這也意味着在某個字符失配時,該字符對應的next 值會告訴你下一步匹配中,模式串應該跳到哪個位置。
複雜度:
(設S長度爲n,P長度爲m)
後綴數組
給定一個串 s[1…n],將所有後綴排序
rk[i]:s[i…n] 的排名
sa[i]: rk 爲 i 的後綴是哪個
倍增+歸併排序實現
height[i]:S[sa[i]…n] 和 S[sa[i+1]…n] 的LCP
height[i]>=height[rk[sa[i]-1]]-1
基本操作:
LCP(X,Y)=Min(H[rk[x]]…H[rk[y]-1])
最長重複子串
不可重疊最長重複子串
本質不同的子串個數
求 S[l…r] 的出現次數
後綴自動機
後綴樹:將每個後綴插入 Trie 中得到一個 Trie 樹,然後縮掉所有隻有一個兒子的點
我們用 fail[x] 表示 x 在後綴樹上的父親
x 代表了一系列子串:這些串的長度是 [len[fail[x]]+1…len[x]],左端點的集合是Right(x):x 子樹里有哪些後綴
go[x][c]:x 代表的串左邊加上 c 後得到的串是哪個結點
len[go[x][c]]>=len[x]+1
構造:每次往前加點
由於太過毒瘤請謹慎食用代碼
複雜度:
結點數爲 O(N)
邊數爲 O(N)
基本應用:
(本質不同 通俗的說即 長的不一樣)
求本質不同的子串個數
求每個前綴/後綴的本質不同的子串個數
求兩個串 S,T 的最長公共子串
求LCP(S[i…n],S[j…n])
求第 K 小子串的值(EXT:支持多次詢問,每次輸出長度)
求一個子串的出現次數
求不重疊最長重複子串
總結
分治和圖論思路感覺都還能理解,但細節和代碼實現還需要細細品味,最好是寫幾道題練手。
分治整體有點模式化?
不過處理跨mid的信息有點繁瑣(怎麼感覺天天分類討論)
圖論我覺得重點是建立模型,以及對一些性質的思考
kmp講的有點淺。。本來期待着AC自動機的。。
SA和SAM兩個巨坑只能之後填了
說是組合計數。。
其實就提了一下歐拉函數。。其他全是容斥。。
(基本掛機)
歐拉函數
1~n之間與n互質的數的個數(課件上就這一句話)
//線性篩1~n的歐拉函數
inline void euler(int n)
{
memset(vis,0,sizeof(vis));
memset(prime,0,sizeof(prime));
memset(phi,0,sizeof(phi));
int tot=0;
phi[1]=1;
for(int i=2;i<=n;i++)
{
if(vis[i]==0) {
vis[i]=i;
prime[++tot]=i;
phi[i]=i-1;
}
for(int j=1;j<=tot&&prime[j]*i<n;j++)
{
if(prime[j]>vis[i] ) {
break;
}
vis[i*prime[j]]=prime[j];
if(i%prime[j]) {
phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
else phi[i*prime[j]]=phi[i]*prime[j];
}
}
}
容斥原理
容斥原理是一種重要的組合數學方法,可以讓你求解任意大小的集合,或者計算複合事件的概率。
容斥原理可以描述如下:
列出題目中的n個條件。
求滿足這n個條件中每一個的方案的個數。 枚舉這些條件的所有2^n個集合。
考慮一個集合x,令不滿足x中所有條件的方案有A個。如果x的大小是奇數,給答案減去A,不然給答案加上A。
另一種理解方法:
要計算幾個集合並集的大小,我們要先將所有單個集合的大小計算出來,然後減去所有兩個集合相交的部分,再加回所有三個集合相交的部分,再減去所有四個集合相交的部分,依此類推,一直計算到所有集合相交的部分。
上述過程轉化爲數學公式如下:
爲題目給出的個條件
我們設爲的所有集合,那麼可以寫的更簡潔
關於容斥的其它內容點這裏
補集思想
正難則反。 滿足條件的=全部的-不滿足條件的。 容斥原理可以看成補集思想的一部分
如:
連通圖的數量=圖的總數-不連通圖的數量。
歐拉圖的數量也能相同的方法計算