精心整理2万字c++知识点
制作不易,求一鍵三連~
文章目錄
- 1、基本數(shù)據(jù)結(jié)構(gòu)
- 數(shù)組
- 鏈表
- 隊(duì)列、單調(diào)隊(duì)列、雙端隊(duì)列
- 棧
- 2、中極數(shù)據(jù)結(jié)構(gòu)
- 堆
- 并查集與帶權(quán)并查集
- hash表
- 自然溢出
- 雙hash
- 3、高級(jí)數(shù)據(jù)結(jié)構(gòu)
- 樹(shù)狀數(shù)組
- 線段樹(shù)及其合并
- Zkw線段樹(shù)
- Fhq線樹(shù)
- 超哥線段樹(shù)
- 平衡樹(shù)
- Treap隨機(jī)平衡二叉樹(shù)
- Splay伸展樹(shù)
- Scapegoat Tree替罪羊樹(shù)
- 后綴平衡樹(shù)
- 塊狀數(shù)組、塊狀鏈表
- 樹(shù)套樹(shù)
- 線段樹(shù)套線段樹(shù)
- 線段樹(shù)套平衡樹(shù)
- 平衡樹(shù)套線段樹(shù)
- 可并堆
- 左偏樹(shù)
- 配對(duì)堆
- KDTree、四分樹(shù)
- 舞蹈鏈(DLX)、二進(jìn)制分組
- 劃分樹(shù)
- 4、可持久化數(shù)據(jù)結(jié)構(gòu)
- 可持久化線段樹(shù)(主席樹(shù))
- 可持久化平衡樹(shù)
- 可持久化塊狀數(shù)組
- 5、字符串相關(guān)算法及數(shù)據(jù)結(jié)構(gòu)
- KMP
- AC自動(dòng)機(jī)
- 后綴數(shù)組
- 后綴樹(shù)
- 后綴自動(dòng)機(jī)
- 字典樹(shù)Trie
- Manacher
- 6、圖論相關(guān)
- 最小生成樹(shù)
- Prim
- Kruskal
- 最短路、次短路、K短路
- Spfa
- Dijkstra
- Floyd
- 圖的聯(lián)通
- 連通分量
- 割點(diǎn)、割邊
- 網(wǎng)絡(luò)流
- 最大流
- 最小割
- 費(fèi)用流
- 分?jǐn)?shù)規(guī)劃
- 樹(shù)相關(guān)
- 樹(shù)上倍增、公共祖先
- 樹(shù)鏈剖分
- 樹(shù)的分治算法(點(diǎn)分治、邊分治、動(dòng)態(tài)樹(shù)分治)
- 動(dòng)態(tài)樹(shù)(LCT、樹(shù)分塊)
- 虛樹(shù)
- prufer編碼
- 拓?fù)渑判?/li>
- 歐拉圖
- 二分圖
- KM算法
- 匈牙利算法
- 仙人掌算法
- 7、數(shù)學(xué)相關(guān)
- (擴(kuò)展)歐幾里得算法、篩法、快速冪
- 斐蜀定理
- 更相減損術(shù)
- 歐拉函數(shù)與降冪
- 費(fèi)馬小定理
- 排列組合
- Lucas定理
- 楊輝三角
- 乘法逆元
- 矩陣乘法
- 數(shù)學(xué)期望與概率
- 博弈論
- Sg函數(shù)
- 樹(shù)上刪邊游戲
- 拉格朗日乘子法
- 中國(guó)剩余定理
- 線性規(guī)劃與網(wǎng)絡(luò)流
- 辛普森積分
- 模擬線性方程組
- 容斥原理與莫比烏斯反演
- 快速傅立葉變換
- 大步小步BSGS法(擴(kuò)展)
- 高斯消元
- 線性篩
- Min25篩與杜教篩
- 母函數(shù)
- Burnside引理與Polya計(jì)數(shù)
- Miller-Robin素?cái)?shù)檢測(cè)
- Pollard大數(shù)分解
- 8、動(dòng)態(tài)規(guī)劃
- 基礎(chǔ)形式(記憶化搜索、斯坦納樹(shù)、背包九講)
- 背包dp
- 線性dp
- 區(qū)間dp
- 狀壓dp
- 環(huán)形dp
- 樹(shù)形dp
- 數(shù)位dp
- 倍增dp
- 插頭dp
- 斜率優(yōu)化與四邊形不等式優(yōu)化
- 環(huán)+外向樹(shù)上的dp
- 9、計(jì)算幾何
- 計(jì)算幾何基礎(chǔ)
- 三位計(jì)算幾何初步
- 梯形剖分與三角形剖分
- 凸包
- 旋轉(zhuǎn)卡殼
- 半平面交
- pick定理
- 掃描線
- 10、搜索相關(guān)
- dfs、bfs
- A*算法
- 迭代加深搜索(IDA*)、雙向廣搜
- 11、特殊算法
- 莫隊(duì)算法、樹(shù)上莫隊(duì)
- 模擬退火
- 爬山算法
- 隨機(jī)增量算法
- 12、其他重要工具與方法
- 模擬與貪心
- 二分法、三分法(求偏導(dǎo))
- 分治、CDQ分治
- 高精度
- 離線
- ST表
- 13、STL
- map
- priority_queue
- set
- bitset
- rope
- 14、非常見(jiàn)算法
- 朱劉算法
- 弦圖與區(qū)間圖
1、基本數(shù)據(jù)結(jié)構(gòu)
數(shù)組
數(shù)組(Array)是有序的元素序列。 [1] 若將有限個(gè)類(lèi)型相同的變量的集合命名,那么這個(gè)名稱(chēng)為數(shù)組名。組成數(shù)組的各個(gè)變量稱(chēng)為數(shù)組的分量,也稱(chēng)為數(shù)組的元素,有時(shí)也稱(chēng)為下標(biāo)變量。用于區(qū)分?jǐn)?shù)組的各個(gè)元素的數(shù)字編號(hào)稱(chēng)為下標(biāo)。數(shù)組是在程序設(shè)計(jì)中,為了處理方便, 把具有相同類(lèi)型的若干元素按有序的形式組織起來(lái)的一種形式。 [1] 這些有序排列的同類(lèi)數(shù)據(jù)元素的集合稱(chēng)為數(shù)組。
數(shù)組是用于儲(chǔ)存多個(gè)相同類(lèi)型數(shù)據(jù)的集合。
鏈表
鏈表是一種物理存儲(chǔ)單元上非連續(xù)、非順序的存儲(chǔ)結(jié)構(gòu),數(shù)據(jù)元素的邏輯順序是通過(guò)鏈表中的指針鏈接次序?qū)崿F(xiàn)的。鏈表由一系列結(jié)點(diǎn)(鏈表中每一個(gè)元素稱(chēng)為結(jié)點(diǎn))組成,結(jié)點(diǎn)可以在運(yùn)行時(shí)動(dòng)態(tài)生成。每個(gè)結(jié)點(diǎn)包括兩個(gè)部分:一個(gè)是存儲(chǔ)數(shù)據(jù)元素的數(shù)據(jù)域,另一個(gè)是存儲(chǔ)下一個(gè)結(jié)點(diǎn)地址的指針域。 相比于線性表順序結(jié)構(gòu),操作復(fù)雜。由于不必須按順序存儲(chǔ),鏈表在插入的時(shí)候可以達(dá)到O(1)的復(fù)雜度,比另一種線性表順序表快得多,但是查找一個(gè)節(jié)點(diǎn)或者訪問(wèn)特定編號(hào)的節(jié)點(diǎn)則需要O(n)的時(shí)間,而線性表和順序表相應(yīng)的時(shí)間復(fù)雜度分別是O(logn)和O(1)。
使用鏈表結(jié)構(gòu)可以克服數(shù)組鏈表需要預(yù)先知道數(shù)據(jù)大小的缺點(diǎn),鏈表結(jié)構(gòu)可以充分利用計(jì)算機(jī)內(nèi)存空間,實(shí)現(xiàn)靈活的內(nèi)存動(dòng)態(tài)管理。但是鏈表失去了數(shù)組隨機(jī)讀取的優(yōu)點(diǎn),同時(shí)鏈表由于增加了結(jié)點(diǎn)的指針域,空間開(kāi)銷(xiāo)比較大。鏈表最明顯的好處就是,常規(guī)數(shù)組排列關(guān)聯(lián)項(xiàng)目的方式可能不同于這些數(shù)據(jù)項(xiàng)目在記憶體或磁盤(pán)上順序,數(shù)據(jù)的存取往往要在不同的排列順序中轉(zhuǎn)換。鏈表允許插入和移除表上任意位置上的節(jié)點(diǎn),但是不允許隨機(jī)存取。鏈表有很多種不同的類(lèi)型:單向鏈表,雙向鏈表以及循環(huán)鏈表。鏈表可以在多種編程語(yǔ)言中實(shí)現(xiàn)。像Lisp和Scheme這樣的語(yǔ)言的內(nèi)建數(shù)據(jù)類(lèi)型中就包含了鏈表的存取和操作。程序語(yǔ)言或面向?qū)ο笳Z(yǔ)言,如C,C++和Java依靠易變工具來(lái)生成鏈表。
隊(duì)列、單調(diào)隊(duì)列、雙端隊(duì)列
隊(duì)列是一種特殊的線性表,特殊之處在于它只允許在表的前端(front)進(jìn)行刪除操作,而在表的后端(rear)進(jìn)行插入操作,和棧一樣,隊(duì)列是一種操作受限制的線性表。進(jìn)行插入操作的端稱(chēng)為隊(duì)尾,進(jìn)行刪除操作的端稱(chēng)為隊(duì)頭。
單調(diào)隊(duì)列,即單調(diào)遞減或單調(diào)遞增的隊(duì)列。使用頻率不高,但在有些程序中會(huì)有非同尋常的作用。
deque(double-ended queue,雙端隊(duì)列)是一種具有隊(duì)列和棧的性質(zhì)的數(shù)據(jù)結(jié)構(gòu)。雙端隊(duì)列中的元素可以從兩端彈出,相比list增加[]運(yùn)算符重載。
棧
棧(stack)又名堆棧,它是一種運(yùn)算受限的線性表。限定僅在表尾進(jìn)行插入和刪除操作的線性表。這一端被稱(chēng)為棧頂,相對(duì)地,把另一端稱(chēng)為棧底。向一個(gè)棧插入新元素又稱(chēng)作進(jìn)棧、入棧或壓棧,它是把新元素放到棧頂元素的上面,使之成為新的棧頂元素;從一個(gè)棧刪除元素又稱(chēng)作出棧或退棧,它是把棧頂元素刪除掉,使其相鄰的元素成為新的棧頂元素。
2、中極數(shù)據(jù)結(jié)構(gòu)
堆
堆(Heap)是計(jì)算機(jī)科學(xué)中一類(lèi)特殊的數(shù)據(jù)結(jié)構(gòu)的統(tǒng)稱(chēng)。堆通常是一個(gè)可以被看做一棵完全二叉樹(shù)的數(shù)組對(duì)象。
并查集與帶權(quán)并查集
并查集,在一些有N個(gè)元素的集合應(yīng)用問(wèn)題中,我們通常是在開(kāi)始時(shí)讓每個(gè)元素構(gòu)成一個(gè)單元素的集合,然后按一定順序?qū)儆谕唤M的元素所在的集合合并,其間要反復(fù)查找一個(gè)元素在哪個(gè)集合中。這一類(lèi)問(wèn)題近幾年來(lái)反復(fù)出現(xiàn)在信息學(xué)的國(guó)際國(guó)內(nèi)賽題中。其特點(diǎn)是看似并不復(fù)雜,但數(shù)據(jù)量極大,若用正常的數(shù)據(jù)結(jié)構(gòu)來(lái)描述的話,往往在空間上過(guò)大,計(jì)算機(jī)無(wú)法承受;即使在空間上勉強(qiáng)通過(guò),運(yùn)行的時(shí)間復(fù)雜度也極高,根本就不可能在比賽規(guī)定的運(yùn)行時(shí)間(1~3秒)內(nèi)計(jì)算出試題需要的結(jié)果,只能用并查集來(lái)描述。
并查集是一種樹(shù)型的數(shù)據(jù)結(jié)構(gòu),用于處理一些不相交集合(disjoint sets)的合并及查詢問(wèn)題。常常在使用中以森林來(lái)表示。
帶權(quán)并查集是普通并查集的進(jìn)階版本,功能更加強(qiáng)大。
普通并查集只能判斷兩個(gè)元素是否在一個(gè)集合中,帶權(quán)并查集可以維護(hù)集合元素之間的關(guān)系,這個(gè)關(guān)系由每個(gè)元素的權(quán)值維護(hù)。
對(duì)權(quán)值的維護(hù),我們需要在find(),unite()操作中分別進(jìn)行修改。
hash表
散列表(Hash table,也叫哈希表),是根據(jù)關(guān)鍵碼值(Key value)而直接進(jìn)行訪問(wèn)的數(shù)據(jù)結(jié)構(gòu)。也就是說(shuō),它通過(guò)把關(guān)鍵碼值映射到表中一個(gè)位置來(lái)訪問(wèn)記錄,以加快查找的速度。這個(gè)映射函數(shù)叫做散列函數(shù),存放記錄的數(shù)組叫做散列表。
給定表M,存在函數(shù)f(key),對(duì)任意給定的關(guān)鍵字值key,代入函數(shù)后若能得到包含該關(guān)鍵字的記錄在表中的地址,則稱(chēng)表M為哈希(Hash)表,函數(shù)f(key)為哈希(Hash) 函數(shù)。
自然溢出
溢出哈希表是在hash 表填入過(guò)程中,將沖突的元素順序填入到溢出表中,而當(dāng)查找過(guò)程中發(fā)現(xiàn)沖突時(shí),就在溢出表中進(jìn)行順序查找。
雙hash
雙重哈希屬于開(kāi)放地址哈希中的一種解決沖突方案,也就是說(shuō)如果一次哈希不能解決問(wèn)題的時(shí)候,要再次哈希
3、高級(jí)數(shù)據(jù)結(jié)構(gòu)
樹(shù)狀數(shù)組
樹(shù)狀數(shù)組或二叉索引樹(shù)(英語(yǔ):Binary Indexed Tree),又以其發(fā)明者命名為Fenwick樹(shù),最早由Peter M. Fenwick于1994年以A New Data Structure for Cumulative Frequency Tables為題發(fā)表在SOFTWARE PRACTICE AND EXPERIENCE。其初衷是解決數(shù)據(jù)壓縮里的累積頻率(Cumulative Frequency)的計(jì)算問(wèn)題,現(xiàn)多用于高效計(jì)算數(shù)列的前綴和, 區(qū)間和。
線段樹(shù)及其合并
線段樹(shù)合并說(shuō)全來(lái)就是動(dòng)態(tài)開(kāi)點(diǎn)權(quán)值線段樹(shù)合并,所以你需要掌握權(quán)值線段樹(shù)的基本知識(shí)以及知道什么是動(dòng)態(tài)開(kāi)點(diǎn)
對(duì)于兩個(gè)普通權(quán)值線段樹(shù)如果暴力合并的話復(fù)雜度將會(huì)是n log ?n,更別說(shuō)是合并n棵權(quán)值線段樹(shù)了(炸空間、炸內(nèi)存),但是在動(dòng)態(tài)開(kāi)點(diǎn)權(quán)值線段樹(shù)中,這一操作是可以優(yōu)化為log n的。
Zkw線段樹(shù)
遞歸式線段樹(shù)的常數(shù)很大,經(jīng)常被卡,而zkw線段樹(shù)的常數(shù)很小
Fhq線樹(shù)
FHQ Treap,又名無(wú)旋Treap,是一種不需要旋轉(zhuǎn)的平衡樹(shù),是范浩強(qiáng)基于Treap發(fā)明的。FHQ Treap具有代碼短,易理解,速度快的優(yōu)點(diǎn)。(當(dāng)然跟紅黑樹(shù)等更高級(jí)的平衡樹(shù)比一下就是……)至少它在OI中算是很優(yōu)秀的數(shù)據(jù)結(jié)構(gòu)了。
超哥線段樹(shù)
超哥線段樹(shù),實(shí)際上是線段樹(shù)的標(biāo)記永久化。
平衡樹(shù)
平衡樹(shù)(Balance Tree,BT) 指的是,任意節(jié)點(diǎn)的子樹(shù)的高度差都小于等于1。常見(jiàn)的符合平衡樹(shù)的有,B樹(shù)(多路平衡搜索樹(shù))、AVL樹(shù)(二叉平衡搜索樹(shù))等。平衡樹(shù)可以完成集合的一系列操作, 時(shí)間復(fù)雜度和空間復(fù)雜度相對(duì)于“2-3樹(shù)”要低,在完成集合的一系列操作中始終保持平衡,為大型數(shù)據(jù)庫(kù)的組織、索引提供了一條新的途徑。 [1]
設(shè)“2-3 樹(shù)”的每個(gè)結(jié)點(diǎn)存放一組與應(yīng)用問(wèn)題有關(guān)的數(shù)據(jù), 且有一個(gè)關(guān)鍵字 (>0的整數(shù)) 作為標(biāo)識(shí)。關(guān)鍵字的存放規(guī)則如下:對(duì)于結(jié)點(diǎn)X, 設(shè)左、中、右子樹(shù)均不空, 則左子樹(shù)任一結(jié)點(diǎn)的關(guān)鍵字小于中子樹(shù)中任一結(jié)點(diǎn)的關(guān)鍵字;中子樹(shù)中任一結(jié)點(diǎn)的關(guān)鍵字小于結(jié)點(diǎn)X的關(guān)鍵字;而X的關(guān)鍵字又小于右子樹(shù)中任一結(jié)點(diǎn)的關(guān)鍵字, 稱(chēng)這樣的“2-3樹(shù)”為平衡樹(shù)。[1]
Treap隨機(jī)平衡二叉樹(shù)
樹(shù)堆(Treap)是二叉排序樹(shù)(Binary Sort Tree)與堆(Heap)結(jié)合產(chǎn)生的一種擁有堆性質(zhì)的二叉排序樹(shù)。
Splay伸展樹(shù)
Splay(伸展樹(shù))是一種二叉排序樹(shù),它能在O(log2 n)的時(shí)間內(nèi)完成插入、查找和刪除操作。
Splay(伸展樹(shù))能實(shí)現(xiàn)線段樹(shù)不能實(shí)現(xiàn)的操作,比如區(qū)間翻轉(zhuǎn)。
Splay的核心函數(shù)是旋轉(zhuǎn)操作,將點(diǎn)x旋轉(zhuǎn)至點(diǎn)k下面。特別的rotate (x, 0)表示把x旋轉(zhuǎn)至根。旋轉(zhuǎn)操作不會(huì)改變每個(gè)節(jié)點(diǎn)在該樹(shù)的中序遍歷中的位置。
旋轉(zhuǎn)的目的:在每次查詢、修改操作完,將操作的節(jié)點(diǎn)旋轉(zhuǎn)到根,就像是輸入法,常用的詞匯會(huì)在第一頁(yè)就出現(xiàn),如果是第一次用,則需要翻好幾頁(yè)。可以保證均攤的時(shí)間復(fù)雜度為 [公式] 。
Scapegoat Tree替罪羊樹(shù)
替罪羊樹(shù)是計(jì)算機(jī)科學(xué)中,一種基于部分重建的自平衡二叉搜索樹(shù)。在替罪羊樹(shù)上,插入或刪除節(jié)點(diǎn)的平攤最壞時(shí)間復(fù)雜度是O(log n),搜索節(jié)點(diǎn)的最壞時(shí)間復(fù)雜度是O(log n)
后綴平衡樹(shù)
如果需要?jiǎng)討B(tài)維護(hù)后綴數(shù)組,支持在字符串前端插入一個(gè)字符,詢問(wèn)后綴的大小關(guān)系,如何做呢?
這是一個(gè)不斷插入的問(wèn)題,可以從增量的角度考慮。我們?cè)谇岸瞬迦胍粋€(gè)字符,其實(shí)就是插入了一個(gè)新的后綴。我們的問(wèn)題其實(shí)就是這個(gè)后綴排名多少。我們可以用平衡樹(shù)維護(hù)一下后綴數(shù)組,從根節(jié)點(diǎn)開(kāi)始二分比較這個(gè)后綴的大小,看看它應(yīng)該被插到哪里。現(xiàn)在問(wèn)題就變成了快速比較一個(gè)新的后綴和一個(gè)已有的后綴。
如果這個(gè)新的后綴和當(dāng)前比較的后綴的首字符不同,那么比較結(jié)果是顯然的;如果新的后綴和當(dāng)前比較的后綴的首字符相同,那么問(wèn)題就轉(zhuǎn)化成了比較原來(lái)已有的兩個(gè)后綴的大小關(guān)系。我們?cè)谄胶鈽?shù)的每個(gè)節(jié)點(diǎn)上維護(hù)一個(gè)值x∈[0,1],代表它的大小,左兒子為的關(guān)鍵值為[l,mid],右兒子的關(guān)鍵值為[mid,r],那么只要直接比較這個(gè)值就可以啦。
然而如果平衡樹(shù)的深度過(guò)大,那么這個(gè)值會(huì)爆實(shí)數(shù)的精度。所以我們采用深度為O(logn)的平衡樹(shù)。但如果平衡樹(shù)需要旋轉(zhuǎn),那么它的子樹(shù)需要全部重新計(jì)算關(guān)鍵值。所以我們需要使用重量平衡樹(shù),其子樹(shù)大小均攤O(logn),所以每次插入旋轉(zhuǎn)后整個(gè)子樹(shù)重算一下。
塊狀數(shù)組、塊狀鏈表
塊狀數(shù)組,即把一個(gè)數(shù)組分為幾個(gè)塊,塊內(nèi)信息整體保存,若查詢時(shí)遇到兩邊不完整的塊直接暴力查詢。一般情況下,塊的長(zhǎng)度為O(√n) 。
樹(shù)套樹(shù)
線段樹(shù)套線段樹(shù)
樹(shù)套樹(shù)寫(xiě)法還是比較好理解的,不過(guò)要是讓自己硬套的話可能很不容易套出來(lái)的
這里的二維線段樹(shù),外層線段樹(shù)是對(duì)方陣的正投影,而內(nèi)層線段樹(shù)是對(duì)方陣的側(cè)投影
線段樹(shù)套平衡樹(shù)
線段樹(shù)的作用是區(qū)間修改和查詢,平衡樹(shù)的作用是查詢第k大,k的排名,前驅(qū),后繼。這兩個(gè)結(jié)合起來(lái),就變成了可以區(qū)間修改和查詢第k大,k的排名,前驅(qū),后繼的數(shù)據(jù)結(jié)構(gòu):樹(shù)套樹(shù)-線段樹(shù)套平衡樹(shù)。
平衡樹(shù)套線段樹(shù)
線段樹(shù)維護(hù)的是區(qū)間,然后對(duì)于線段樹(shù)維護(hù)的區(qū)間的所有數(shù)字都維護(hù)一個(gè)平衡樹(shù),然后所有的操作都對(duì)每個(gè)平衡樹(shù)單獨(dú)處理。
可并堆
可并堆,顧名思義,就是可以合并的堆。堆滿足一個(gè)性質(zhì),就是當(dāng)前節(jié)點(diǎn),都大于或者等于他的所有子樹(shù)上的節(jié)點(diǎn),自然在這里我所講的是結(jié)點(diǎn)的權(quán)值。顯而易見(jiàn),既然可并堆是堆的一種,容易推出,可并堆也滿足這個(gè)性質(zhì)。
左偏樹(shù)
左偏樹(shù)(英語(yǔ):leftist tree或leftist heap),也可稱(chēng)為左偏堆、左傾堆,是計(jì)算機(jī)科學(xué)中的一種樹(shù),是一種優(yōu)先隊(duì)列實(shí)現(xiàn)方式,屬于可并堆,在信息學(xué)中十分常見(jiàn),在統(tǒng)計(jì)問(wèn)題、最值問(wèn)題、模擬問(wèn)題和貪心問(wèn)題等等類(lèi)型的題目中,左偏樹(shù)都有著廣泛的應(yīng)用。斜堆是比左偏樹(shù)更為一般的數(shù)據(jù)結(jié)構(gòu)。
配對(duì)堆
配對(duì)堆是一種實(shí)現(xiàn)簡(jiǎn)單、均攤復(fù)雜度優(yōu)越的堆數(shù)據(jù)結(jié)構(gòu),由Michael Fredman、羅伯特·塞奇威克、Daniel Sleator、羅伯特·塔揚(yáng)于1986年發(fā)明。配對(duì)堆是一種多叉樹(shù),并且可以被認(rèn)為是一種簡(jiǎn)化的斐波那契堆。對(duì)于實(shí)現(xiàn)例如普林姆最小生成樹(shù)算法等算法,配對(duì)堆是一個(gè)更優(yōu)的選擇,
KDTree、四分樹(shù)
kd-tree(k-dimensional樹(shù)的簡(jiǎn)稱(chēng)),是一種對(duì)k維空間中的實(shí)例點(diǎn)進(jìn)行存儲(chǔ)以便對(duì)其進(jìn)行快速檢索的樹(shù)形數(shù)據(jù)結(jié)構(gòu)。 [1] 主要應(yīng)用于多維空間關(guān)鍵數(shù)據(jù)的搜索(如:范圍搜索和最近鄰搜索)。K-D樹(shù)是二進(jìn)制空間分割樹(shù)的特殊的情況。
在計(jì)算機(jī)科學(xué)里,k-d樹(shù)( k-維樹(shù)的縮寫(xiě))是在k維歐幾里德空間組織點(diǎn)的數(shù)據(jù)結(jié)構(gòu)。k-d樹(shù)可以使用在多種應(yīng)用場(chǎng)合,如多維鍵值搜索(例:范圍搜尋及最鄰近搜索)。k-d樹(shù)是空間二分樹(shù)(Binary space partitioning )的一種特殊情況。 [2]
四分樹(shù)就是用一個(gè)類(lèi)似于線段樹(shù)的東西來(lái)維護(hù)一個(gè)矩陣,就是每個(gè)點(diǎn)有四個(gè)兒子
然后每個(gè)兒子代表切分之后的一塊區(qū)域
舞蹈鏈(DLX)、二進(jìn)制分組
舞蹈鏈(Dancing Links)算法在求解精確覆蓋問(wèn)題時(shí)效率驚人。
二進(jìn)制分組就是把操作的數(shù)量二進(jìn)制拆分,每個(gè)二進(jìn)制位數(shù)用數(shù)據(jù)結(jié)構(gòu)維護(hù)
合并的時(shí)候,暴力重構(gòu)
每次查詢,從logn個(gè)塊依次用維護(hù)的數(shù)據(jù)結(jié)構(gòu)查詢
劃分樹(shù)
劃分樹(shù)定義為,它的每一個(gè)節(jié)點(diǎn)保存區(qū)間[lft,rht]所有元素,元素順序與原數(shù)組(輸入)相同,但是,兩個(gè)子樹(shù)的元素為該節(jié)點(diǎn)所有元素排序后(rht-lft+1)/2個(gè)進(jìn)入左子樹(shù),其余的到右子樹(shù),同時(shí)維護(hù)一個(gè)num域,num[i]表示lft->i這個(gè)點(diǎn)有多少個(gè)進(jìn)入了左子樹(shù)。
4、可持久化數(shù)據(jù)結(jié)構(gòu)
可持久化線段樹(shù)(主席樹(shù))
主席樹(shù),也叫做可持久化線段樹(shù),準(zhǔn)確來(lái)說(shuō),應(yīng)該叫做可持久化權(quán)值線段樹(shù),因?yàn)槠渲械拿恳活w樹(shù)都是一顆權(quán)值線段樹(shù)。
所謂權(quán)值線段樹(shù),就是指線段樹(shù)的葉子節(jié)點(diǎn)保存的是當(dāng)前值的個(gè)數(shù)。這樣說(shuō)起來(lái)比較抽象,下面用具體例子來(lái)簡(jiǎn)單闡述。
可持久化平衡樹(shù)
treap = tree + heap,即同時(shí)滿足二叉搜索樹(shù)和堆的性質(zhì)。
為了使樹(shù)盡可能的保證兩邊的大小平衡,所以有一個(gè)key值,使他滿足堆得性質(zhì),來(lái)維護(hù)樹(shù)的平衡,key值是隨機(jī)的。
treap有一般平衡樹(shù)的功能,前驅(qū)、后繼、第k大、查詢排名、插入、刪除。也比較好寫(xiě)
可持久化塊狀數(shù)組
題目中要求可以查詢歷史狀態(tài),最暴力的想法是開(kāi)a[m][n]的二維數(shù)組,每次修改暴力復(fù)制并修改,每次查詢暴力掃描,時(shí)間復(fù)雜度是O(mn)的,但這顯然是不行的.
這個(gè)時(shí)候其實(shí)很容易想到線段樹(shù),但線段樹(shù)維護(hù)的是當(dāng)前狀態(tài)而無(wú)法維護(hù)歷史狀態(tài),一種暴力的想法是開(kāi)m棵線段樹(shù),但這樣MLE的風(fēng)險(xiǎn)可謂巨大。
但我們發(fā)現(xiàn),因?yàn)轭}目修改的是一個(gè)點(diǎn)的值,在線段樹(shù)上,會(huì)被修改的點(diǎn)只有l(wèi)ogn個(gè),因此可以每次只新建這logn個(gè)結(jié)點(diǎn)
5、字符串相關(guān)算法及數(shù)據(jù)結(jié)構(gòu)
KMP
KMP算法是一種改進(jìn)的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人們稱(chēng)它為克努特—莫里斯—普拉特操作(簡(jiǎn)稱(chēng)KMP算法)。KMP算法的核心是利用匹配失敗后的信息,盡量減少模式串與主串的匹配次數(shù)以達(dá)到快速匹配的目的。具體實(shí)現(xiàn)就是通過(guò)一個(gè)next()函數(shù)實(shí)現(xiàn),函數(shù)本身包含了模式串的局部匹配信息。KMP算法的時(shí)間復(fù)雜度O(m+n) [1] 。
AC自動(dòng)機(jī)
Aho-Corasick automaton,該算法在1975年產(chǎn)生于貝爾實(shí)驗(yàn)室,是著名的多模匹配算法。
要學(xué)會(huì)AC自動(dòng)機(jī),我們必須知道什么是Trie,也就是字典樹(shù)。Trie樹(shù),又稱(chēng)單詞查找樹(shù)或鍵樹(shù),是一種樹(shù)形結(jié)構(gòu),是一種哈希樹(shù)的變種。典型應(yīng)用是用于統(tǒng)計(jì)和排序大量的字符串(但不僅限于字符串),所以經(jīng)常被搜索引擎系統(tǒng)用于文本詞頻統(tǒng)計(jì)。
后綴數(shù)組
在計(jì)算機(jī)科學(xué)里, 后綴數(shù)組(英語(yǔ):suffix array)是一個(gè)通過(guò)對(duì)字符串的所有后綴經(jīng)過(guò)排序后得到的數(shù)組。此數(shù)據(jù)結(jié)構(gòu)被運(yùn)用于全文索引、數(shù)據(jù)壓縮算法、以及生物信息學(xué)。
后綴數(shù)組被烏迪·曼伯爾與尤金·邁爾斯于1990年提出,作為對(duì)后綴樹(shù)的一種替代,更簡(jiǎn)單以及節(jié)省空間。它們也被Gaston Gonnet 于1987年獨(dú)立發(fā)現(xiàn),并命名為“PAT數(shù)組”。
后綴樹(shù)
后綴樹(shù)(Suffix tree)是一種數(shù)據(jù)結(jié)構(gòu),能快速解決很多關(guān)于字符串的問(wèn)題。后綴樹(shù)的概念最早由Weiner于1973年提出,既而由McCreight在1976年和Ukkonen在1992年和1995年加以改進(jìn)完善。
一個(gè)string S的后綴樹(shù)是一個(gè)邊(edge)被標(biāo)記為字符串的樹(shù)。因此每一個(gè)S的后綴都唯一對(duì)應(yīng)一條從根節(jié)點(diǎn)到葉節(jié)點(diǎn)的路徑。這樣就形成了一個(gè)S的后綴的基數(shù)樹(shù)(radix tree)。后綴樹(shù)是前綴樹(shù)(trie)里的一個(gè)特殊類(lèi)型。
后綴自動(dòng)機(jī)
首先,后綴自動(dòng)機(jī)是一種有限狀態(tài)自動(dòng)機(jī),他可以識(shí)別且僅識(shí)別一個(gè)字符串的后綴。但是這不并不是后綴自動(dòng)機(jī)強(qiáng)大的地方,我可以說(shuō)如果把AC自動(dòng)機(jī)反向插入我同樣可以做到這一點(diǎn)。
后綴自動(dòng)機(jī)真正的用處在于:它可以識(shí)別一個(gè)串的所有子串。
非常優(yōu)秀的是后綴自動(dòng)機(jī)只會(huì)有O(n)個(gè)節(jié)點(diǎn),也就是說(shuō)在字符集看做常數(shù)的情況下,對(duì)于后綴自動(dòng)機(jī)的構(gòu)建可以做到O(n)。
后綴自動(dòng)機(jī)不同于AC自動(dòng)機(jī)的地方在于:它并不是一棵樹(shù),不看prarent鏈的話,后綴自動(dòng)機(jī)是一張DAG,這就讓后綴自動(dòng)機(jī)每一個(gè)節(jié)點(diǎn)的意義玄妙了起來(lái)。
字典樹(shù)Trie
又稱(chēng)單詞查找樹(shù),Trie樹(shù),是一種樹(shù)形結(jié)構(gòu),是一種哈希樹(shù)的變種。典型應(yīng)用是用于統(tǒng)計(jì),排序和保存大量的字符串(但不僅限于字符串),所以經(jīng)常被搜索引擎系統(tǒng)用于文本詞頻統(tǒng)計(jì)。它的優(yōu)點(diǎn)是:利用字符串的公共前綴來(lái)減少查詢時(shí)間,最大限度地減少無(wú)謂的字符串比較,查詢效率比哈希樹(shù)高。
Manacher
馬拉車(chē)算法 Manacher‘s Algorithm 是用來(lái)查找一個(gè)字符串的最長(zhǎng)回文子串的線性方法,由一個(gè)叫Manacher的人在1975年發(fā)明的,這個(gè)方法的最大貢獻(xiàn)是在于將時(shí)間復(fù)雜度提升到了線性。
6、圖論相關(guān)
最小生成樹(shù)
一個(gè)有 n 個(gè)結(jié)點(diǎn)的連通圖的生成樹(shù)是原圖的極小連通子圖,且包含原圖中的所有 n 個(gè)結(jié)點(diǎn),并且有保持圖連通的最少的邊。 [1] 最小生成樹(shù)可以用kruskal(克魯斯卡爾)算法或prim(普里姆)算法求出。
Prim
普里姆算法(Prim算法),圖論中的一種算法,可在加權(quán)連通圖里搜索最小生成樹(shù)。意即由此算法搜索到的邊子集所構(gòu)成的樹(shù)中,不但包括了連通圖里的所有頂點(diǎn)(英語(yǔ):Vertex (graph theory)),且其所有邊的權(quán)值之和亦為最小。該算法于1930年由捷克數(shù)學(xué)家沃伊捷赫·亞爾尼克(英語(yǔ):Vojtěch Jarník)發(fā)現(xiàn);并在1957年由美國(guó)計(jì)算機(jī)科學(xué)家羅伯特·普里姆(英語(yǔ):Robert C. Prim)獨(dú)立發(fā)現(xiàn);1959年,艾茲格·迪科斯徹再次發(fā)現(xiàn)了該算法。因此,在某些場(chǎng)合,普里姆算法又被稱(chēng)為DJP算法、亞爾尼克算法或普里姆-亞爾尼克算法。
Kruskal
克魯斯卡爾算法是求連通網(wǎng)的最小生成樹(shù)的另一種方法。與普里姆算法不同,它的時(shí)間復(fù)雜度為O(eloge)(e為網(wǎng)中的邊數(shù)),所以,適合于求邊稀疏的網(wǎng)的最小生成樹(shù) [1] 。
最短路、次短路、K短路
Spfa
SPFA 算法是 Bellman-Ford算法 的隊(duì)列優(yōu)化算法的別稱(chēng),通常用于求含負(fù)權(quán)邊的單源最短路徑,以及判負(fù)權(quán)環(huán)。SPFA 最壞情況下復(fù)雜度和樸素 Bellman-Ford 相同,為 O(VE)。
Dijkstra
迪杰斯特拉算法(Dijkstra)是由荷蘭計(jì)算機(jī)科學(xué)家狄克斯特拉于1959年提出的,因此又叫狄克斯特拉算法。是從一個(gè)頂點(diǎn)到其余各頂點(diǎn)的最短路徑算法,解決的是有權(quán)圖中最短路徑問(wèn)題。迪杰斯特拉算法主要特點(diǎn)是從起始點(diǎn)開(kāi)始,采用貪心算法的策略,每次遍歷到始點(diǎn)距離最近且未訪問(wèn)過(guò)的頂點(diǎn)的鄰接節(jié)點(diǎn),直到擴(kuò)展到終點(diǎn)為止。 [1]
Floyd
Floyd算法又稱(chēng)為插點(diǎn)法,是一種利用動(dòng)態(tài)規(guī)劃的思想尋找給定的加權(quán)圖中多源點(diǎn)之間最短路徑的算法,與Dijkstra算法類(lèi)似。該算法名稱(chēng)以創(chuàng)始人之一、1978年圖靈獎(jiǎng)獲得者、斯坦福大學(xué)計(jì)算機(jī)科學(xué)系教授羅伯特·弗洛伊德命名。 [1]
圖的聯(lián)通
連通分量
無(wú)向圖G的極大連通子圖稱(chēng)為G的連通分量( Connected Component)。任何連通圖的連通分量只有一個(gè),即是其自身,非連通的無(wú)向圖有多個(gè)連通分量。
割點(diǎn)、割邊
在一個(gè)無(wú)向圖中,如果有一個(gè)頂點(diǎn)集合,刪除這個(gè)頂點(diǎn)集合以及這個(gè)集合中所有頂點(diǎn)相關(guān)聯(lián)的邊以后,圖的連通分量增多,就稱(chēng)這個(gè)點(diǎn)集為割點(diǎn)集合。
如果某個(gè)割點(diǎn)集合只含有一個(gè)頂點(diǎn)X(也即{X}是一個(gè)割點(diǎn)集合),那么X稱(chēng)為一個(gè)割點(diǎn)。
假設(shè)有連通圖G,e是其中一條邊,如果G-e是不連通的,則邊e是圖G的一條割邊。此情形下,G-e必包含兩個(gè)連通分支。
網(wǎng)絡(luò)流
網(wǎng)絡(luò)流(network-flows)是一種類(lèi)比水流的解決問(wèn)題方法,與線性規(guī)劃密切相關(guān)。網(wǎng)絡(luò)流的理論和應(yīng)用在不斷發(fā)展,出現(xiàn)了具有增益的流、多終端流、多商品流以及網(wǎng)絡(luò)流的分解與合成等新課題。網(wǎng)絡(luò)流的應(yīng)用已遍及通訊、運(yùn)輸、電力、工程規(guī)劃、任務(wù)分派、設(shè)備更新以及計(jì)算機(jī)輔助設(shè)計(jì)等眾多領(lǐng)域。
最大流
管道網(wǎng)絡(luò)中每條邊的最大通過(guò)能力(容量)是有限的,實(shí)際流量不超過(guò)容量。
最大流問(wèn)題(maximum flow problem),一種組合最優(yōu)化問(wèn)題,就是要討論如何充分利用裝置的能力,使得運(yùn)輸?shù)牧髁孔畲?#xff0c;以取得最好的效果。求最大流的標(biāo)號(hào)算法最早由福特和福克遜于1956年提出,20世紀(jì)50年代福特(Ford)、福克遜(Fulkerson)建立的“網(wǎng)絡(luò)流理論”,是網(wǎng)絡(luò)應(yīng)用的重要組成成分。
最小割
最小割,圖中所有的割中,邊權(quán)值和最小的割為最小割。
費(fèi)用流
最小費(fèi)用流問(wèn)題是一種組合最優(yōu)化問(wèn)題,也是網(wǎng)絡(luò)流理論研究的一個(gè)重要問(wèn)題。
分?jǐn)?shù)規(guī)劃
樹(shù)相關(guān)
樹(shù)上倍增、公共祖先
LCA(least common ancestors)最近公共祖先
指的就是對(duì)于一棵有根樹(shù),若結(jié)點(diǎn)z既是x的祖先,也是y的祖先,那么z就是結(jié)點(diǎn)x和y的最近公共祖先。
對(duì)于有根樹(shù)T的兩個(gè)結(jié)點(diǎn)u、v,最近公共祖先LCA(T,u,v)表示一個(gè)結(jié)點(diǎn)x,滿足x是u和v的祖先且x的深度盡可能大。在這里,一個(gè)節(jié)點(diǎn)也可以是它自己的祖先。
樹(shù)鏈剖分
樹(shù)鏈剖分,計(jì)算機(jī)術(shù)語(yǔ),指一種對(duì)樹(shù)進(jìn)行劃分的算法,它先通過(guò)輕重邊剖分將樹(shù)分為多條鏈,保證每個(gè)點(diǎn)屬于且只屬于一條鏈,然后再通過(guò)數(shù)據(jù)結(jié)構(gòu)(樹(shù)狀數(shù)組、BST、SPLAY、線段樹(shù)等)來(lái)維護(hù)每一條鏈。
樹(shù)的分治算法(點(diǎn)分治、邊分治、動(dòng)態(tài)樹(shù)分治)
點(diǎn)分治,顧名思義就是基于樹(shù)上的節(jié)點(diǎn)進(jìn)行分治。
如果我們?cè)谏钊胍稽c(diǎn)呢?對(duì)于點(diǎn)的拆開(kāi)其實(shí)就是對(duì)于樹(shù)的拆開(kāi)。
所以我認(rèn)為點(diǎn)分治的本質(zhì)其實(shí)是將一棵樹(shù)拆分成許多棵子樹(shù)處理,并不斷進(jìn)行。
這應(yīng)該也是點(diǎn)分治的精髓。
邊分治的分治過(guò)程與點(diǎn)分治類(lèi)似,同樣每次分治時(shí)找到一條分治中心邊使這條邊兩端的兩個(gè)聯(lián)通塊中較大的一個(gè)盡量小。以分治中心邊為界限,恰好將當(dāng)前分治的聯(lián)通塊中的點(diǎn)分成了兩部分,統(tǒng)計(jì)路徑經(jīng)過(guò)分治中心邊的答案,然后將分治中心邊斷開(kāi),遞歸分治中心邊兩端的兩個(gè)聯(lián)通塊。
動(dòng)態(tài)樹(shù)分治,顧名思義,解決待修改的樹(shù)分治問(wèn)題。原本的樹(shù)分治基于邊或者重心的分治可以解決大多數(shù)靜態(tài)樹(shù)鏈問(wèn)題,但是待修改怎么辦?其實(shí)很簡(jiǎn)單,因?yàn)闃?shù)結(jié)構(gòu)是不變的,就是樹(shù)分治的基礎(chǔ)結(jié)構(gòu)不變,對(duì)于修改和詢問(wèn),只需要在第一次樹(shù)分治的基礎(chǔ)上用一些數(shù)據(jù)結(jié)構(gòu)維護(hù)一些信息即可。
動(dòng)態(tài)樹(shù)(LCT、樹(shù)分塊)
動(dòng)態(tài)樹(shù)問(wèn)題 ,是一類(lèi)要求維護(hù)一個(gè)有根樹(shù)森林,支持對(duì)樹(shù)的分割, 合并等操作的問(wèn)題。由RobertE.Tarjan為首的科學(xué)家們提出解決算法Link-Cut Trees,簡(jiǎn)稱(chēng)LCT。
虛樹(shù)
虛樹(shù),是對(duì)于一棵給定的節(jié)點(diǎn)數(shù)為 n 的樹(shù) T,構(gòu)造一棵新的樹(shù) T’ 使得總結(jié)點(diǎn)數(shù)最小且包含指定的某幾個(gè)節(jié)點(diǎn)和他們的LCA。
prufer編碼
prufer是無(wú)根樹(shù)的一種編碼方式,一棵無(wú)根樹(shù)和一個(gè)prufer編碼唯一對(duì)應(yīng),也就是一棵樹(shù)有唯一的prufer編碼,而一個(gè)prufer編碼對(duì)應(yīng)一棵唯一的樹(shù)。
拓?fù)渑判?/h2>
對(duì)一個(gè)有向無(wú)環(huán)圖(Directed Acyclic Graph簡(jiǎn)稱(chēng)DAG)G進(jìn)行拓?fù)渑判?#xff0c;是將G中所有頂點(diǎn)排成一個(gè)線性序列,使得圖中任意一對(duì)頂點(diǎn)u和v,若邊<u,v>∈E(G),則u在線性序列中出現(xiàn)在v之前。通常,這樣的線性序列稱(chēng)為滿足拓?fù)浯涡?Topological Order)的序列,簡(jiǎn)稱(chēng)拓?fù)湫蛄小:?jiǎn)單的說(shuō),由某個(gè)集合上的一個(gè)偏序得到該集合上的一個(gè)全序,這個(gè)操作稱(chēng)之為拓?fù)渑判颉?[1]
歐拉圖
歐拉圖是指通過(guò)圖(無(wú)向圖或有向圖)中所有邊且每邊僅通過(guò)一次通路,相應(yīng)的回路稱(chēng)為歐拉回路。具有歐拉回路的圖稱(chēng)為歐拉圖(Euler Graph),具有歐拉通路而無(wú)歐拉回路的圖稱(chēng)為半歐拉圖。對(duì)歐拉圖的一個(gè)現(xiàn)代擴(kuò)展是蜘蛛圖,它向歐拉圖增加了可以連接的存在點(diǎn)。這給予歐拉圖析取特征。歐拉圖已經(jīng)有了合取特征(就是說(shuō)區(qū)定義了有著與起來(lái)的那些性質(zhì)的對(duì)象在區(qū)中的存在)。所以蜘蛛圖允許使用歐拉圖建模邏輯或的條件。
二分圖
二分圖又稱(chēng)作二部圖,是圖論中的一種特殊模型。 設(shè)G=(V,E)是一個(gè)無(wú)向圖,如果頂點(diǎn)V可分割為兩個(gè)互不相交的子集(A,B),并且圖中的每條邊(i,j)所關(guān)聯(lián)的兩個(gè)頂點(diǎn)i和j分別屬于這兩個(gè)不同的頂點(diǎn)集(i in A,j in B),則稱(chēng)圖G為一個(gè)二分圖。
KM算法
KM算法用來(lái)求二分圖最大權(quán)完美匹配。
匈牙利算法
匈牙利算法是一種在多項(xiàng)式時(shí)間內(nèi)求解任務(wù)分配問(wèn)題的組合優(yōu)化算法,并推動(dòng)了后來(lái)的原始對(duì)偶方法。1955年,庫(kù)恩(W.W.Kuhn)利用匈牙利數(shù)學(xué)家康尼格(D.K?nig)的一個(gè)定理構(gòu)造了這個(gè)解法,故稱(chēng)為匈牙利法。 [2]
仙人掌算法
仙人掌圖:每條邊至多在一個(gè)環(huán)上的圖。
仙人掌圖中每個(gè)環(huán)相當(dāng)于一個(gè)點(diǎn)雙連通分量,那么用Tarjan算法處理dfs樹(shù)。
7、數(shù)學(xué)相關(guān)
(擴(kuò)展)歐幾里得算法、篩法、快速冪
擴(kuò)展歐幾里得算法是歐幾里得算法(又叫輾轉(zhuǎn)相除法)的擴(kuò)展。除了計(jì)算a、b兩個(gè)整數(shù)的最大公約數(shù),此算法還能找到整數(shù)x、y(其中一個(gè)很可能是負(fù)數(shù))。通常談到最大公因子時(shí), 我們都會(huì)提到一個(gè)非常基本的事實(shí): 給予二整數(shù) a 與 b, 必存在有整數(shù) x 與 y 使得ax + by = gcd(a,b)。有兩個(gè)數(shù)a,b,對(duì)它們進(jìn)行輾轉(zhuǎn)相除法,可得它們的最大公約數(shù)——這是眾所周知的。然后,收集輾轉(zhuǎn)相除法中產(chǎn)生的式子,倒回去,可以得到ax+by=gcd(a,b)的整數(shù)解。
篩法(挨拉托色尼篩法)是一種用來(lái)求所有小于N的素?cái)?shù)的方法。把從2(素?cái)?shù)是指大于1的自然數(shù))開(kāi)始的某一范圍內(nèi)的正整數(shù)從小到大按順序排列,逐步篩掉非素?cái)?shù)留下素?cái)?shù)。
顧名思義,快速冪就是快速算底數(shù)的n次冪。其時(shí)間復(fù)雜度為 O(log?N), 與樸素的O(N)相比效率有了極大的提高。
斐蜀定理
在數(shù)論中,裴蜀定理是一個(gè)關(guān)于最大公約數(shù)(或最大公約式)的定理,裴蜀定理得名于法國(guó)數(shù)學(xué)家艾蒂安·裴蜀。
裴蜀定理說(shuō)明了對(duì)任何整數(shù) a、b和它們的最大公約數(shù) d ,關(guān)于未知數(shù) x以及 y 的線性的丟番圖方程(稱(chēng)為裴蜀等式)。
更相減損術(shù)
更相減損術(shù)是出自《九章算術(shù)》的一種求最大公約數(shù)的算法,它原本是為約分而設(shè)計(jì)的,但它適用于任何需要求最大公約數(shù)的場(chǎng)合。
歐拉函數(shù)與降冪
在數(shù)論,對(duì)正整數(shù)n,歐拉函數(shù)是小于n的正整數(shù)中與n互質(zhì)的數(shù)的數(shù)目。
把一個(gè)多項(xiàng)式的各項(xiàng)按照某個(gè)字母的指數(shù)從大到小的順序排列,叫做這一字母的降冪。如ab+(-2ba)+a為a的降冪。
費(fèi)馬小定理
費(fèi)馬小定理 (Fermat’s little theorem) 是數(shù)論中的一個(gè)重要定理,在1636年提出。如果p是一個(gè)質(zhì)數(shù),而整數(shù)a不是p的倍數(shù),則有a ^ (p - 1) ≡ 1 (mod p)。[1]
排列組合
Lucas定理
Lucas定理是用來(lái)求 c(n,m) mod p,p為素?cái)?shù)的值。
楊輝三角
楊輝三角,是二項(xiàng)式系數(shù)在三角形中的一種幾何排列,中國(guó)南宋數(shù)學(xué)家楊輝1261年所著的《詳解九章算法》一書(shū)中出現(xiàn)。在歐洲,帕斯卡(1623----1662)在1654年發(fā)現(xiàn)這一規(guī)律,所以這個(gè)表又叫做帕斯卡三角形。帕斯卡的發(fā)現(xiàn)比楊輝要遲393年,比賈憲遲600年。 [1]
乘法逆元
乘法逆元,是指數(shù)學(xué)領(lǐng)域群G中任意一個(gè)元素a,都在G中有唯一的逆元a‘,具有性質(zhì)a×a’=a’×a=e,其中e為該群的單位元。
矩陣乘法
矩陣相乘最重要的方法是一般矩陣乘積。它只有在第一個(gè)矩陣的列數(shù)(column)和第二個(gè)矩陣的行數(shù)(row)相同時(shí)才有意義 [1] 。一般單指矩陣乘積時(shí),指的便是一般矩陣乘積。一個(gè)m×n的矩陣就是m×n個(gè)數(shù)排成m行n列的一個(gè)數(shù)陣。由于它把許多數(shù)據(jù)緊湊地集中到了一起,所以有時(shí)候可以簡(jiǎn)便地表示一些復(fù)雜的模型,如電力系統(tǒng)網(wǎng)絡(luò)模型。 [2]
數(shù)學(xué)期望與概率
在概率論和統(tǒng)計(jì)學(xué)中,數(shù)學(xué)期望(mean)(或均值,亦簡(jiǎn)稱(chēng)期望)是試驗(yàn)中每次可能結(jié)果的概率乘以其結(jié)果的總和,是最基本的數(shù)學(xué)特征之一。它反映隨機(jī)變量平均取值的大小。
需要注意的是,期望值并不一定等同于常識(shí)中的“期望”——“期望值”也許與每一個(gè)結(jié)果都不相等。期望值是該變量輸出值的平均數(shù)。期望值并不一定包含于變量的輸出值集合里。
大數(shù)定律表明,隨著重復(fù)次數(shù)接近無(wú)窮大,數(shù)值的算術(shù)平均值幾乎肯定地收斂于期望值。
博弈論
博弈論,又稱(chēng)為對(duì)策論(Game Theory)、賽局理論等,既是現(xiàn)代數(shù)學(xué)的一個(gè)新分支,也是運(yùn)籌學(xué)的一個(gè)重要學(xué)科。
博弈論主要研究公式化了的激勵(lì)結(jié)構(gòu)間的相互作用,是研究具有斗爭(zhēng)或競(jìng)爭(zhēng)性質(zhì)現(xiàn)象的數(shù)學(xué)理論和方法。博弈論考慮游戲中的個(gè)體的預(yù)測(cè)行為和實(shí)際行為,并研究它們的優(yōu)化策略。生物學(xué)家使用博弈理論來(lái)理解和預(yù)測(cè)進(jìn)化論的某些結(jié)果。
博弈論已經(jīng)成為經(jīng)濟(jì)學(xué)的標(biāo)準(zhǔn)分析工具之一。在金融學(xué)、證券學(xué)、生物學(xué)、經(jīng)濟(jì)學(xué)、國(guó)際關(guān)系、計(jì)算機(jī)科學(xué)、政治學(xué)、軍事戰(zhàn)略和其他很多學(xué)科都有廣泛的應(yīng)用。
Sg函數(shù)
給定一個(gè)有向無(wú)環(huán)圖和一個(gè)起始頂點(diǎn)上的一枚棋子,兩名選手交替的將這枚棋子沿有向邊進(jìn)行移動(dòng),無(wú)法移 動(dòng)者判負(fù)。事實(shí)上,這個(gè)游戲可以認(rèn)為是所有公平組合游戲的抽象模型。
樹(shù)上刪邊游戲
在某一棵樹(shù)上刪除一條邊,同時(shí)刪去所有在刪除后不再與根相連的部分
雙方輪流操作,無(wú)法再進(jìn)行刪除者判定為失敗
一個(gè)游戲中有多棵樹(shù),我們把ta們的根都放在地板上,方便之后的處理
在此,我們討論的將是公平游戲,即雙方都可以刪除任意的樹(shù)邊
我們稱(chēng)這個(gè)游戲?yàn)?#xff1a;Green Hachenbush(樹(shù)上公平刪邊游戲)
之所以強(qiáng)調(diào)是公平博弈,是因?yàn)檫€有另一種刪邊游戲,是不公平的,參與者雙方一方只能刪除藍(lán)邊,一方只能刪除紅邊,而綠邊雙方都可以刪除
拉格朗日乘子法
在數(shù)學(xué)最優(yōu)問(wèn)題中,拉格朗日乘數(shù)法(以數(shù)學(xué)家約瑟夫·路易斯·拉格朗日命名)是一種尋找變量受一個(gè)或多個(gè)條件所限制的多元函數(shù)的極值的方法。這種方法將一個(gè)有n 個(gè)變量與k 個(gè)約束條件的最優(yōu)化問(wèn)題轉(zhuǎn)換為一個(gè)有n + k個(gè)變量的方程組的極值問(wèn)題,其變量不受任何約束。這種方法引入了一種新的標(biāo)量未知數(shù),即拉格朗日乘數(shù):約束方程的梯度(gradient)的線性組合里每個(gè)向量的系數(shù)。 [1] 此方法的證明牽涉到偏微分,全微分或鏈法,從而找到能讓設(shè)出的隱函數(shù)的微分為零的未知數(shù)的值。
中國(guó)剩余定理
孫子定理是中國(guó)古代求解一次同余式組(見(jiàn)同余)的方法。是數(shù)論中一個(gè)重要定理。又稱(chēng)中國(guó)余數(shù)定理。一元線性同余方程組問(wèn)題最早可見(jiàn)于中國(guó)南北朝時(shí)期(公元5世紀(jì))的數(shù)學(xué)著作《孫子算經(jīng)》卷下第二十六題,叫做“物不知數(shù)”問(wèn)題,原文如下:
有物不知其數(shù),三三數(shù)之剩二,五五數(shù)之剩三,七七數(shù)之剩二。問(wèn)物幾何?即,一個(gè)整數(shù)除以三余二,除以五余三,除以七余二,求這個(gè)整數(shù)。《孫子算經(jīng)》中首次提到了同余方程組問(wèn)題,以及以上具體問(wèn)題的解法,因此在中文數(shù)學(xué)文獻(xiàn)中也會(huì)將中國(guó)剩余定理稱(chēng)為孫子定理。
線性規(guī)劃與網(wǎng)絡(luò)流
線性規(guī)劃(Linear programming,簡(jiǎn)稱(chēng)LP),是運(yùn)籌學(xué)中研究較早、發(fā)展較快、應(yīng)用廣泛、方法較成熟的一個(gè)重要分支,它是輔助人們進(jìn)行科學(xué)管理的一種數(shù)學(xué)方法。研究線性約束條件下線性目標(biāo)函數(shù)的極值問(wèn)題的數(shù)學(xué)理論和方法。英文縮寫(xiě)LP。
線性規(guī)劃是運(yùn)籌學(xué)的一個(gè)重要分支,廣泛應(yīng)用于軍事作戰(zhàn)、經(jīng)濟(jì)分析、經(jīng)營(yíng)管理和工程技術(shù)等方面。為合理地利用有限的人力、物力、財(cái)力等資源作出的最優(yōu)決策,提供科學(xué)的依據(jù)。
辛普森積分
辛普森積分法是一種用拋物線近似函數(shù)曲線來(lái)求定積分?jǐn)?shù)值解的方法。把積分區(qū)間等分成若干段,對(duì)被積函數(shù)在每一段上使用辛普森公式,根據(jù)其在每一段的兩端和中點(diǎn)處的值近似為拋物線,逐段積分后加起來(lái),即得到原定積分的數(shù)值解。辛普森積分法比梯形法則更精確,二者都是牛頓-柯特斯公式(Newton-Cotes)的特例。
模擬線性方程組
這個(gè)問(wèn)題的源自《孫子算經(jīng)》,其中有這樣一道算術(shù)題:“今有物不知其數(shù),三三數(shù)之剩二,五五數(shù)之剩三,七七數(shù)之剩二,問(wèn)物幾何?”按照今天的話來(lái)說(shuō):一個(gè)數(shù)除以3余2,除以5余3,除以7余2,求這個(gè)數(shù).這樣的問(wèn)題,也有人稱(chēng)為“韓信點(diǎn)兵”.它形成了一類(lèi)問(wèn)題,也就是初等數(shù)論中解同余式.這類(lèi)問(wèn)題的有解條件和解的方法被稱(chēng)為“中國(guó)剩余定理”,這是由中國(guó)人首先提出的。
容斥原理與莫比烏斯反演
在計(jì)數(shù)時(shí),必須注意沒(méi)有重復(fù),沒(méi)有遺漏。為了使重疊部分不被重復(fù)計(jì)算,人們研究出一種新的計(jì)數(shù)方法,這種方法的基本思想是:先不考慮重疊的情況,把包含于某內(nèi)容中的所有對(duì)象的數(shù)目先計(jì)算出來(lái),然后再把計(jì)數(shù)時(shí)重復(fù)計(jì)算的數(shù)目排斥出去,使得計(jì)算的結(jié)果既無(wú)遺漏又無(wú)重復(fù),這種計(jì)數(shù)的方法稱(chēng)為容斥原理。 [1]
莫比烏斯反演是數(shù)論數(shù)學(xué)中很重要的內(nèi)容,可以用于解決很多組合數(shù)學(xué)的問(wèn)題。
快速傅立葉變換
快速傅里葉變換 (fast Fourier transform), 即利用計(jì)算機(jī)計(jì)算離散傅里葉變換(DFT)的高效、快速計(jì)算方法的統(tǒng)稱(chēng),簡(jiǎn)稱(chēng)FFT。快速傅里葉變換是1965年由J.W.庫(kù)利和T.W.圖基提出的。采用這種算法能使計(jì)算機(jī)計(jì)算離散傅里葉變換所需要的乘法次數(shù)大為減少,特別是被變換的抽樣點(diǎn)數(shù)N越多,FFT算法計(jì)算量的節(jié)省就越顯著。
大步小步BSGS法(擴(kuò)展)
計(jì)算(y^x ≡ z mod p) 中 (x) 的解。
高斯消元
數(shù)學(xué)上,高斯消元法(或譯:高斯消去法),是線性代數(shù)規(guī)劃中的一個(gè)算法,可用來(lái)為線性方程組求解。但其算法十分復(fù)雜,不常用于加減消元法,求出矩陣的秩,以及求出可逆方陣的逆矩陣。不過(guò),如果有過(guò)百萬(wàn)條等式時(shí),這個(gè)算法會(huì)十分省時(shí)。一些極大的方程組通常會(huì)用迭代法以及花式消元來(lái)解決。當(dāng)用于一個(gè)矩陣時(shí),高斯消元法會(huì)產(chǎn)生出一個(gè)“行梯陣式”。高斯消元法可以用在電腦中來(lái)解決數(shù)千條等式及未知數(shù)。亦有一些方法特地用來(lái)解決一些有特別排列的系數(shù)的方程組。 [1]
線性篩
在剛接觸編程語(yǔ)言時(shí),對(duì)于尋找素?cái)?shù),第一時(shí)間想到的便是二重循環(huán)暴力查找,其復(fù)雜度O(n),通過(guò)循環(huán)中只判斷到根號(hào)n可以優(yōu)化一些,不過(guò)復(fù)雜度也達(dá)不到預(yù)期。在數(shù)論的學(xué)習(xí)中,我學(xué)到了埃氏篩法,O(nloglogn)的算法,而在一些數(shù)據(jù)范圍達(dá)到1e7這樣的題目中,也很難讓人滿意,于是我便學(xué)習(xí)了歐拉篩法,也即 O(n)的線性篩法。
Min25篩與杜教篩
考慮一個(gè)積性函數(shù)F(x),用來(lái)快速計(jì)算前綴和
∑i=1nF(i)
當(dāng)然,這個(gè)積性函數(shù)要滿足F(x),x∈Prime可以用多項(xiàng)式表示
同時(shí),F(xk),x∈Prime要能夠快速計(jì)算答案
杜教篩是用來(lái)求一類(lèi)積性函數(shù)的前綴和
它通過(guò)各種轉(zhuǎn)化,最終利用數(shù)論分塊的思想來(lái)降低復(fù)雜度
假設(shè)我們現(xiàn)在要求S(n)=∑ni=1f(i),f(i)為積性函數(shù),n?1012
直接求肯定是不好求的,不過(guò)現(xiàn)在假設(shè)有另一個(gè)積性函數(shù)g
我們來(lái)求它們狄利克雷卷積的前綴和
∑i=1n(g?f)=∑i=1n∑d∣ig(d)f(id)
=∑d=1ng(d)∑d|if(id)
=∑d=1ng(d)∑i=1ndf(i)
=∑d=1ng(d)S(nd)
然后就化不動(dòng)了,不過(guò)我們發(fā)現(xiàn)我們化出了nd!
但是S(n)怎么求呢?
容斥一下
g(1)S(n)=∑d=1ng(d)S(nd)?∑d=2ng(d)S(nd)
前半部分是狄利克雷卷積的前綴和的形式
后半部分可以數(shù)論分塊。這樣看起來(lái)就好搞多了
現(xiàn)在我們的問(wèn)題是,如何選擇g才能使得上面這個(gè)式子好算
這個(gè)就要因情況而定了
母函數(shù)
生成函數(shù)即母函數(shù),是組合數(shù)學(xué)中尤其是計(jì)數(shù)方面的一個(gè)重要理論和工具。生成函數(shù)有普通型生成函數(shù)和指數(shù)型生成函數(shù)兩種,其中普通型用的比較多。形式上說(shuō),普通型生成函數(shù)用于解決多重集的組合問(wèn)題,而指數(shù)型母函數(shù)用于解決多重集的排列問(wèn)題。母函數(shù)還可以解決遞歸數(shù)列的通項(xiàng)問(wèn)題(例如使用母函數(shù)解決斐波那契數(shù)列的通項(xiàng)公式)。
Burnside引理與Polya計(jì)數(shù)
伯恩賽德引理(Burnside’s lemma),也叫伯恩賽德計(jì)數(shù)定理(Burnside’s counting theorem),柯西-弗羅貝尼烏斯引理(Cauchy-Frobenius lemma)或軌道計(jì)數(shù)定理(orbit-counting theorem),是群論中一個(gè)結(jié)果,在考慮對(duì)稱(chēng)的計(jì)數(shù)中經(jīng)常很有用。該結(jié)論被冠以多個(gè)人的名字,其中包括威廉·伯恩賽德(William Burnside)、波利亞、柯西和弗羅貝尼烏斯。這個(gè)命題不屬于伯恩賽德自己,他只是在自己的書(shū)中《有限群論 On the Theory of Groups of Finite Order》引用了,而將其歸于弗羅貝尼烏斯 (1887)。
Burnside定理之所以能夠計(jì)數(shù)不等價(jià)著色數(shù),與它能夠計(jì)算C(f)有關(guān),而C中的原色不變是f保持的,通過(guò)考慮置換的循環(huán)結(jié)構(gòu)計(jì)算可變得容易簡(jiǎn)便。
Miller-Robin素?cái)?shù)檢測(cè)
快速概率測(cè)素?cái)?shù)的算法------MillerRobin(),適用于測(cè)試單個(gè)素?cái)?shù),出錯(cuò)概率比計(jì)算機(jī)本身出錯(cuò)的概率還要低
為(1/4)^(s),一般s取50就可以認(rèn)為是準(zhǔn)確測(cè)試出了。
算法是基于費(fèi)馬小定理(format),二次探測(cè)定理 x*x % p == 1 ,若P為素?cái)?shù),則x的解只能是x = 1或者x = p - 1)加上迭代乘法判斷的Miller算法
Pollard大數(shù)分解
Pollard_rho算法的大致流程是 先判斷當(dāng)前數(shù)是否是素?cái)?shù)(Miller_rabin)了,如果是則直接返回。如果不是素?cái)?shù)的話,試圖找到當(dāng)前數(shù)的一個(gè)因子(可以不是質(zhì)因子)。然后遞歸對(duì)該因子和約去這個(gè)因子的另一個(gè)因子進(jìn)行分解。
8、動(dòng)態(tài)規(guī)劃
基礎(chǔ)形式(記憶化搜索、斯坦納樹(shù)、背包九講)
背包dp
背包問(wèn)題(Knapsack problem)是一種組合優(yōu)化的NP完全問(wèn)題。問(wèn)題可以描述為:給定一組物品,每種物品都有自己的重量和價(jià)格,在限定的總重量?jī)?nèi),我們?nèi)绾芜x擇,才能使得物品的總價(jià)格最高。問(wèn)題的名稱(chēng)來(lái)源于如何選擇最合適的物品放置于給定背包中。相似問(wèn)題經(jīng)常出現(xiàn)在商業(yè)、組合數(shù)學(xué),計(jì)算復(fù)雜性理論、密碼學(xué)和應(yīng)用數(shù)學(xué)等領(lǐng)域中。也可以將背包問(wèn)題描述為決定性問(wèn)題,即在總重量不超過(guò)W的前提下,總價(jià)值是否能達(dá)到V?它是在1978年由Merkle和Hellman提出的。
背包問(wèn)題已經(jīng)研究了一個(gè)多世紀(jì),早期的作品可追溯到1897年 [1] 數(shù)學(xué)家托比亞斯·丹齊格(Tobias Dantzig,1884-1956)的早期作品 [2] ,并指的是包裝你最有價(jià)值或有用的物品而不會(huì)超載你的行李的常見(jiàn)問(wèn)題。
線性dp
線性DP是動(dòng)態(tài)規(guī)劃問(wèn)題中的一類(lèi)問(wèn)題,指狀態(tài)之間有線性關(guān)系的動(dòng)態(tài)規(guī)劃問(wèn)題。
區(qū)間dp
區(qū)間dp就是在一段區(qū)間上進(jìn)行動(dòng)態(tài)規(guī)劃。對(duì)于每段區(qū)間,他們的最優(yōu)值都是由幾段更小區(qū)間的最優(yōu)值得到,是分治思想的一種應(yīng)用,將一個(gè)區(qū)間問(wèn)題不斷劃分為更小的區(qū)間直至一個(gè)元素組成的區(qū)間,枚舉他們的組合 ,求合并后的最優(yōu)值。
狀壓dp
狀態(tài)壓縮動(dòng)態(tài)規(guī)劃,就是我們俗稱(chēng)的狀壓DP,是利用計(jì)算機(jī)二進(jìn)制的性質(zhì)來(lái)描述狀態(tài)的一種DP方式。
環(huán)形dp
其實(shí)環(huán)形動(dòng)態(tài)規(guī)劃也是區(qū)間型,只不過(guò)區(qū)間首尾相接
此時(shí)使用記憶化搜索實(shí)現(xiàn),其實(shí)是不容易的
典型例題是能量項(xiàng)鏈
樹(shù)形dp
樹(shù)型動(dòng)態(tài)規(guī)劃就是在“樹(shù)”的數(shù)據(jù)結(jié)構(gòu)上的動(dòng)態(tài)規(guī)劃
數(shù)位dp
數(shù)位dp是一種計(jì)數(shù)用的dp,一般就是要統(tǒng)計(jì)一個(gè)區(qū)間[le,ri]內(nèi)滿足一些條件數(shù)的個(gè)數(shù)。所謂數(shù)位dp,字面意思就是在數(shù)位上進(jìn)行dp咯。數(shù)位還算是比較好聽(tīng)的名字,數(shù)位的含義:一個(gè)數(shù)有個(gè)位、十位、百位、千位…數(shù)的每一位就是數(shù)位啦!
倍增dp
對(duì)于只考慮首位狀態(tài)的DP,考慮用倍增優(yōu)化
插頭dp
基于聯(lián)通性的狀態(tài)壓縮動(dòng)態(tài)規(guī)劃是一類(lèi)很典型的狀態(tài)壓縮動(dòng)態(tài)規(guī)劃問(wèn)題,因?yàn)槠鋲嚎s的本質(zhì)并不像是普通的狀態(tài)壓縮動(dòng)態(tài)規(guī)劃那樣用0或者1來(lái)表示未使用、使用兩種狀態(tài),而是使用數(shù)字來(lái)表示類(lèi)似插頭的狀態(tài),因此,它又被稱(chēng)作插頭DP。
插頭DP本質(zhì)上是一類(lèi)狀態(tài)壓縮DP,因此,依然避免不了其指數(shù)級(jí)別的算法復(fù)雜度,即便如此,它依然要比普通的搜索算法快很多。
斜率優(yōu)化與四邊形不等式優(yōu)化
我們知道,有些DP方程可以轉(zhuǎn)化成DP[i]=f[j]+x[i]的形式,其中f[j]中保存了只與j相關(guān)的量。這樣的DP方程我們可以用單調(diào)隊(duì)列進(jìn)行優(yōu)化,從而使得O(n^2)的復(fù)雜度降到O(n)。
四邊形不等式是一種比較常見(jiàn)的優(yōu)化動(dòng)態(tài)規(guī)劃的方法
環(huán)+外向樹(shù)上的dp
想一想也知道,只要有一個(gè)人討厭另外一個(gè)人,這兩個(gè)人最后是不會(huì)在一起的。
n個(gè)人n條邊(圖不保證聯(lián)通),這就是一個(gè)環(huán)加外向樹(shù)森林
不能同時(shí)取一條邊上的兩個(gè)人,用DP來(lái)實(shí)現(xiàn)
9、計(jì)算幾何
計(jì)算幾何基礎(chǔ)
三位計(jì)算幾何初步
數(shù)學(xué)上,立體幾何(Solid geometry)是3維歐氏空間的幾何的傳統(tǒng)名稱(chēng)—- 因?yàn)閷?shí)際上這大致上就是我們生活的空間。一般作為平面幾何的后續(xù)課程。立體測(cè)繪(Stereometry)處理不同形體的體積的測(cè)量問(wèn)題:圓柱,圓錐, 錐臺(tái), 球,棱柱, 楔, 瓶蓋等等。 畢達(dá)哥拉斯學(xué)派就處理過(guò)球和正多面體,但是棱錐,棱柱,圓錐和圓柱在柏拉圖學(xué)派著手處理之前人們所知甚少。尤得塞斯(Eudoxus)建立了它們的測(cè)量法,證明錐是等底等高的柱體積的三分之一,可能也是第一個(gè)證明球體積和其半徑的立方成正比的。
梯形剖分與三角形剖分
傳說(shuō)把一個(gè)多邊形按照順時(shí)針(或者逆時(shí)針)旋轉(zhuǎn),相鄰兩個(gè)點(diǎn)分別作x軸的垂線(并且這兩個(gè)點(diǎn)相連),就構(gòu)成了梯形,然后定義從點(diǎn)在x軸方向上左到右為正(或者為負(fù)),得到n個(gè)梯形,把面積加起來(lái)就構(gòu)成了多邊形面積,這種剖分就是梯形剖分。
三角剖分是代數(shù)拓?fù)鋵W(xué)里最基本的研究方法。 以曲面為例, 我們把曲面剖開(kāi)成一塊塊碎片,要求滿足下面條件: (1)每塊碎片都是曲邊三角形; (2)曲面上任何兩個(gè)這樣的曲邊三角形,要么不相交,要么恰好相交于一條公共邊(不能同時(shí)交兩條或兩條以上的邊)。 [1]
凸包
凸包(Convex Hull)是一個(gè)計(jì)算幾何(圖形學(xué))中的概念。
在一個(gè)實(shí)數(shù)向量空間V中,對(duì)于給定集合X,所有包含X的凸集的交集S被稱(chēng)為X的凸包。X的凸包可以用X內(nèi)所有點(diǎn)(X1,…Xn)的凸組合來(lái)構(gòu)造.
在二維歐幾里得空間中,凸包可想象為一條剛好包著所有點(diǎn)的橡皮圈。
用不嚴(yán)謹(jǐn)?shù)脑拋?lái)講,給定二維平面上的點(diǎn)集,凸包就是將最外層的點(diǎn)連接起來(lái)構(gòu)成的凸多邊形,它能包含點(diǎn)集中所有的點(diǎn)。
旋轉(zhuǎn)卡殼
”旋轉(zhuǎn)卡殼“是很形象的說(shuō)法,因?yàn)楦鶕?jù)我們枚舉的邊,可以從每個(gè)維護(hù)的點(diǎn)畫(huà)出一條或平行或垂直的直線,為了確保對(duì)于當(dāng)前枚舉的邊的最優(yōu)性,我們的任務(wù)就是使這些直線能將凸包正好卡住。
半平面交
半平面:平面上的直線及其一側(cè)的部分。
pick定理
皮克定理是指一個(gè)計(jì)算點(diǎn)陣中頂點(diǎn)在格點(diǎn)上的多邊形面積公式,該公式可以表示為S=a+b÷2-1,其中a表示多邊形內(nèi)部的點(diǎn)數(shù),b表示多邊形落在格點(diǎn)邊界上的點(diǎn)數(shù),S表示多邊形的面積。
掃描線
掃描線一般運(yùn)用在圖形上面,它和它的字面意思十分相似,就是一條線在整個(gè)圖上掃來(lái)掃去,它一般被用來(lái)解決圖形面積,周長(zhǎng)等問(wèn)題。
10、搜索相關(guān)
dfs、bfs
深度優(yōu)先搜索是一種在開(kāi)發(fā)爬蟲(chóng)早期使用較多的方法。它的目的是要達(dá)到被搜索結(jié)構(gòu)的葉結(jié)點(diǎn)(即那些不包含任何超鏈的HTML文件) 。在一個(gè)HTML文件中,當(dāng)一個(gè)超鏈被選擇后,被鏈接的HTML文件將執(zhí)行深度優(yōu)先搜索,即在搜索其余的超鏈結(jié)果之前必須先完整地搜索單獨(dú)的一條鏈。深度優(yōu)先搜索沿著HTML文件上的超鏈走到不能再深入為止,然后返回到某一個(gè)HTML文件,再繼續(xù)選擇該HTML文件中的其他超鏈。當(dāng)不再有其他超鏈可選擇時(shí),說(shuō)明搜索已經(jīng)結(jié)束。 [1]
寬度優(yōu)先搜索算法(又稱(chēng)廣度優(yōu)先搜索)是最簡(jiǎn)便的圖的搜索算法之一,這一算法也是很多重要的圖的算法的原型。Dijkstra單源最短路徑算法和Prim最小生成樹(shù)算法都采用了和寬度優(yōu)先搜索類(lèi)似的思想。其別名又叫BFS,屬于一種盲目搜尋法,目的是系統(tǒng)地展開(kāi)并檢查圖中的所有節(jié)點(diǎn),以找尋結(jié)果。換句話說(shuō),它并不考慮結(jié)果的可能位置,徹底地搜索整張圖,直到找到結(jié)果為止。
A*算法
A算法,A(A-Star)算法是一種靜態(tài)路網(wǎng)中求解最短路徑最有效的直接搜索方法,也是解決許多搜索問(wèn)題的有效算法。算法中的距離估算值與實(shí)際值越接近,最終搜索速度越快。
迭代加深搜索(IDA*)、雙向廣搜
IDA算法不是基于迭代加深的A算法。
迭代加深只有在狀態(tài)呈指數(shù)級(jí)增長(zhǎng)時(shí)才有較好的效果,而A就是為了防止?fàn)顟B(tài)呈指數(shù)級(jí)增長(zhǎng)的。
IDA算法其實(shí)是同時(shí)運(yùn)用迭代加深與全局最優(yōu)性剪枝。
IDA算法發(fā)明出來(lái)后,可以應(yīng)用在生活的各個(gè)方面,小到你看電腦的屏幕節(jié)能,大到LED燈都采用了此算法,加進(jìn)了LED燈的研發(fā),舉個(gè)例子,計(jì)算機(jī)的節(jié)能,使用了IDA算法根據(jù)光亮調(diào)整亮度,可以減少藍(lán)光輻射以保護(hù)長(zhǎng)時(shí)間盯著電腦的人們,保護(hù)了諸如程序員,OIer等等。
所謂雙向搜索指的是搜索沿兩個(gè)方向同時(shí)進(jìn)行:正向搜索:從初始結(jié)點(diǎn)向目標(biāo)結(jié)點(diǎn)方向搜索;逆向搜索:從目標(biāo)結(jié)點(diǎn)向初始結(jié)點(diǎn)方向搜索;當(dāng)兩個(gè)方向的搜索生成同一子結(jié)點(diǎn)時(shí)終止此搜索過(guò)程。
11、特殊算法
莫隊(duì)算法、樹(shù)上莫隊(duì)
莫隊(duì)算法的思路是,離線情況下對(duì)所有的詢問(wèn)進(jìn)行一個(gè)美妙的SORT (),然后兩個(gè)指針l,r(本題是兩個(gè),其他的題可能會(huì)更多)不斷以看似暴力的方式在區(qū)間內(nèi)跳來(lái)跳去,最終輸出答案。 掌握一個(gè)思想基礎(chǔ):兩個(gè)詢問(wèn)之間的狀態(tài)跳轉(zhuǎn)。
樹(shù)上莫隊(duì),顧名思義就是把莫隊(duì)搬到樹(shù)上。
模擬退火
模擬退火算法來(lái)源于固體退火原理,是一種基于概率的算法,將固體加溫至充分高,再讓其徐徐冷卻,加溫時(shí),固體內(nèi)部粒子隨溫升變?yōu)闊o(wú)序狀,內(nèi)能增大,而徐徐冷卻時(shí)粒子漸趨有序,在每個(gè)溫度都達(dá)到平衡態(tài),最后在常溫時(shí)達(dá)到基態(tài),內(nèi)能減為最小。
爬山算法
爬山算法是一種局部擇優(yōu)的方法,采用啟發(fā)式方法,是對(duì)深度優(yōu)先搜索的一種改進(jìn),它利用反饋信息幫助生成解的決策。 屬于人工智能算法的一種。
隨機(jī)增量算法
隨機(jī)增量算法是計(jì)算幾何的一個(gè)重要算法,它對(duì)理論知識(shí)要求不高,算法時(shí)間復(fù)雜度低,應(yīng)用范圍廣大。 增量法 (Incremental Algorithm) 的思想與第一數(shù)學(xué)歸納法類(lèi)似,它的本質(zhì)是將一個(gè)問(wèn)題化為規(guī)模剛好小一層的子問(wèn)題。 解決子問(wèn)題后加入當(dāng)前的對(duì)象。
12、其他重要工具與方法
模擬與貪心
模擬的缺點(diǎn)是運(yùn)算量大,效率低下。往往需要剪枝才能AC。
貪心算法(又稱(chēng)貪婪算法)是指,在對(duì)問(wèn)題求解時(shí),總是做出在當(dāng)前看來(lái)是最好的選擇。也就是說(shuō),不從整體最優(yōu)上加以考慮,算法得到的是在某種意義上的局部最優(yōu)解 [1] 。
貪心算法不是對(duì)所有問(wèn)題都能得到整體最優(yōu)解,關(guān)鍵是貪心策略的選擇 [1] 。
二分法、三分法(求偏導(dǎo))
二分查找也稱(chēng)折半查找(Binary Search),它是一種效率較高的查找方法。但是,折半查找要求線性表必須采用順序存儲(chǔ)結(jié)構(gòu),而且表中元素按關(guān)鍵字有序排列。 [1]
三分法是二分法的變種,他最基本的用途是求單峰函數(shù)的極值點(diǎn)。
分治、CDQ分治
分治,字面上的解釋是“分而治之”,就是把一個(gè)復(fù)雜的問(wèn)題分成兩個(gè)或更多的相同或相似的子問(wèn)題,再把子問(wèn)題分成更小的子問(wèn)題……直到最后子問(wèn)題可以簡(jiǎn)單的直接求解,原問(wèn)題的解即子問(wèn)題的解的合并。在計(jì)算機(jī)科學(xué)中,分治法就是運(yùn)用分治思想的一種很重要的算法。分治法是很多高效算法的基礎(chǔ),如排序算法(快速排序,歸并排序),傅立葉變換(快速傅立葉變換)等等。
CDQ分治主要思想還是分治的思想,即遞歸處理小范圍信息,之后將處理的信息合并上傳。 一般來(lái)說(shuō),都是先處理左區(qū)間,之后用左區(qū)間更新右區(qū)間,順便更新答案,然后處理右區(qū)間,之后再將兩個(gè)區(qū)間的信息合并。
高精度
高精度算法(High Accuracy Algorithm)是處理大數(shù)字的數(shù)學(xué)計(jì)算方法。在一般的科學(xué)計(jì)算中,會(huì)經(jīng)常算到小數(shù)點(diǎn)后幾百位或者更多,當(dāng)然也可能是幾千億幾百億的大數(shù)字。一般這類(lèi)數(shù)字我們統(tǒng)稱(chēng)為高精度數(shù),高精度算法是用計(jì)算機(jī)對(duì)于超大數(shù)據(jù)的一種模擬加,減,乘,除,乘方,階乘,開(kāi)方等運(yùn)算。對(duì)于非常龐大的數(shù)字無(wú)法在計(jì)算機(jī)中正常存儲(chǔ),于是,將這個(gè)數(shù)字拆開(kāi),拆成一位一位的,或者是四位四位的存儲(chǔ)到一個(gè)數(shù)組中, 用一個(gè)數(shù)組去表示一個(gè)數(shù)字,這樣這個(gè)數(shù)字就被稱(chēng)為是高精度數(shù)。高精度算法就是能處理高精度數(shù)各種運(yùn)算的算法,但又因其特殊性,故從普通數(shù)的算法中分離,自成一家。
離線
離線算法( off line algorithms),是指基于在執(zhí)行算法前輸入數(shù)據(jù)已知的基本假設(shè),也就是說(shuō),對(duì)于一個(gè)離線算法,在開(kāi)始時(shí)就需要知道問(wèn)題的所有輸入數(shù)據(jù),而且在解決一個(gè)問(wèn)題后就要立即輸出結(jié)果。
ST表
ST表 (Sparse Table, 稀疏表 )是一種簡(jiǎn)單的數(shù)據(jù)結(jié)構(gòu),主要用來(lái)解決 RMQ (Range Maximum/Minimum Query,區(qū)間最大/最小值查詢 )問(wèn)題。 它主要應(yīng)用 倍增 的思想,可以實(shí)現(xiàn) 預(yù)處理、 查詢。
13、STL
map
作為關(guān)聯(lián)式容器的一種,map 容器存儲(chǔ)的都是 pair 對(duì)象,也就是用 pair 類(lèi)模板創(chuàng)建的鍵值對(duì)。其中,各個(gè)鍵值對(duì)的鍵和值可以是任意數(shù)據(jù)類(lèi)型,包括 C++ 基本數(shù)據(jù)類(lèi)型(int、double 等)、使用結(jié)構(gòu)體或類(lèi)自定義的類(lèi)型。
priority_queue
不出所料,priority_queue 容器適配器定義了一個(gè)元素有序排列的隊(duì)列。默認(rèn)隊(duì)列頭部的元素優(yōu)先級(jí)最高。因?yàn)樗且粋€(gè)隊(duì)列,所以只能訪問(wèn)第一個(gè)元素,這也意味著優(yōu)先級(jí)最高的元素總是第一個(gè)被處理。但是如何定義“優(yōu)先級(jí)”完全取決于我們自己。如果一個(gè)優(yōu)先級(jí)隊(duì)列記錄的是醫(yī)院里等待接受急救的病人,那么病人病情的嚴(yán)重性就是優(yōu)先級(jí)。如果隊(duì)列元素是銀行的借貸業(yè)務(wù),那么借記可能會(huì)優(yōu)先于信貸。
set
C++ STL 之所以得到廣泛的贊譽(yù),也被很多人使用,不只是提供了像vector, string, list等方便的容器,更重要的是STL封裝了許多復(fù)雜的數(shù)據(jù)結(jié)構(gòu)算法和大量常用數(shù)據(jù)結(jié)構(gòu)操作。vector封裝數(shù)組,list封裝了鏈表,map和set封裝了二叉樹(shù)等,在封裝這些數(shù)據(jù)結(jié)構(gòu)的時(shí)候,STL按照程序員的使用習(xí)慣,以成員函數(shù)方式提供的常用操作,如:插入、排序、刪除、查找等。讓用戶在STL使用過(guò)程中,并不會(huì)感到陌生。
關(guān)于set,必須說(shuō)明的是set關(guān)聯(lián)式容器。set作為一個(gè)容器也是用來(lái)存儲(chǔ)同一數(shù)據(jù)類(lèi)型的數(shù)據(jù)類(lèi)型,并且能從一個(gè)數(shù)據(jù)集合中取出數(shù)據(jù),在set中每個(gè)元素的值都唯一,而且系統(tǒng)能根據(jù)元素的值自動(dòng)進(jìn)行排序。應(yīng)該注意的是set中數(shù)元素的值不能直接被改變。C++ STL中標(biāo)準(zhǔn)關(guān)聯(lián)容器set, multiset, map, multimap內(nèi)部采用的就是一種非常高效的平衡檢索二叉樹(shù):紅黑樹(shù),也成為RB樹(shù)(Red-Black Tree)。RB樹(shù)的統(tǒng)計(jì)性能要好于一般平衡二叉樹(shù),所以被STL選擇作為了關(guān)聯(lián)容器的內(nèi)部結(jié)構(gòu)。
bitset
bitset 模板類(lèi)由若干個(gè)位(bit)組成,它提供一些成員函數(shù),使程序員不必通過(guò)位運(yùn)算就能很方便地訪問(wèn)、修改其中的任意一位。
rope
rope 不屬于標(biāo)準(zhǔn) STL,屬于擴(kuò)展 STL,來(lái)自 pb_ds 庫(kù) (Policy-Based Data Structures)。
14、非常見(jiàn)算法
朱劉算法
朱劉算法是一個(gè) O (nm) 的算法。 當(dāng)然,還有Tarjan巨神的 O (n log n) 的算法。
弦圖與區(qū)間圖
定義弦為一個(gè)環(huán)中連接不相鄰兩個(gè)點(diǎn)的邊。
弦圖為一個(gè)圖,其中任意一個(gè)長(zhǎng)度大于3的環(huán)都包含至少一條弦。
換句話說(shuō):弦圖最大的沒(méi)有弦的環(huán)大小小于3
區(qū)間圖著色問(wèn)題
本篇文章已經(jīng)接近尾聲了,最后來(lái)紀(jì)念一下C語(yǔ)言、UNIX之父——丹尼斯·麥卡利斯泰爾·里奇(Dennis MacAlistair Ritchie)
丹尼斯·里奇(1941年9月9日-2011年10月12日),C語(yǔ)言之父,UNIX之父。曾擔(dān)任朗訊科技公司貝爾實(shí)驗(yàn)室下屬的計(jì)算機(jī)科學(xué)研究中心系統(tǒng)軟件研究部的主任一職。1978年與布萊恩·科爾尼干(Brian W. Kernighan)一起出版了名著《C程序設(shè)計(jì)語(yǔ)言(The C Programming Language)》。此書(shū)已翻譯成多種語(yǔ)言,被譽(yù)為c語(yǔ)言的圣經(jīng)。2011年10月12日(北京時(shí)間為10月13日),丹尼斯·里奇去世,享年70歲。
普通年輕人可能都要搖頭。丹尼斯·里奇是誰(shuí)?
丹尼斯·里奇不像某位來(lái)自硅谷,精致的和少年得志的億萬(wàn)富翁,穿著簡(jiǎn)約黑色的高領(lǐng)毛衣在站滿粉絲的屋子里,演示新酷產(chǎn)品和惡意攻擊對(duì)手。
不,丹尼斯·里奇是一位胡子有些凌亂的計(jì)算機(jī)科學(xué)家,他穿著羊毛衫坐在一間凌亂的辦公室里。
和喬布斯在大學(xué)輟學(xué)不同,他畢業(yè)于哈佛大學(xué),有物理學(xué)和應(yīng)用數(shù)學(xué)的博士學(xué)位。他工作于新澤西的 AT&T 貝爾實(shí)驗(yàn)室,而不是閃閃發(fā)光的硅谷。
雖然存在宗教和意識(shí)形態(tài)的差異。但我們虧欠丹尼斯·里奇很多,超出我們的想象。沒(méi)有他的貢獻(xiàn),現(xiàn)在我們沒(méi)法用個(gè)人計(jì)算機(jī),成熟的軟件應(yīng)用甚至是互聯(lián)網(wǎng)。
沒(méi)有 Android 智能手機(jī),沒(méi)有昂貴的 DVR 和流媒設(shè)備,沒(méi)有喬布斯和蘋(píng)果創(chuàng)造令人驚嘆的 Mac 和 iPad。
沒(méi)有微軟的 Windows 10 和 Surface Book。
沒(méi)有云計(jì)算、沒(méi)有 AWS(亞馬遜網(wǎng)絡(luò)服務(wù),Amazon Web Services),沒(méi)有 Azure(微軟云)。
沒(méi)有“為 XX 而生的應(yīng)用程序”,也沒(méi)有互聯(lián)網(wǎng)這個(gè)東西。
向丹尼斯·里奇致敬 —— 感謝他帶給我們這些技術(shù),讓我們可以成為今天的專(zhuān)家。
總結(jié)
以上是生活随笔為你收集整理的精心整理2万字c++知识点的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Spoon安装步骤
- 下一篇: vcpkg工具+vs2019