ACM國際大學生程序設計競賽(ACM-ICPC)是國際上公認的水平最高、規(guī)模最大、影響最深的計算機專業(yè)競賽,目前全球參與人數達20多萬!禔CM國際大學生程序設計競賽(ACM-ICPC)系列叢書·ACM國際大學生程序設計競賽:算法與實現》作者將76年的教練經驗與積累撰寫成本系列叢書,全面、深入而系統地將ACM-ICPC展現給讀者。本系列叢書包括《ACM國際大學生程序設計競賽:知識與入門》、《ACM國際大學生程序設計競賽:算法與實現》、《ACM國際大學生程序設計競賽:題目與解讀》、《ACM國際大學生程序設計競賽:比賽與思考》等4冊,其中《ACM國際大學生程序設計競賽:知識與入門》介紹了ACM-ICPC的知識及其分類、進階與角色、在線評測系統;《ACM國際大學生程序設計競賽:算法與實現》介紹了ACM-ICPC算法分類、實現及索引;《ACM國際大學生程序設計競賽:題目與解讀》為各類算法配備經典例題及題庫,并提供解題思路;《ACM國際大學生程序設計競賽:比賽與思考》介紹了上海交通大學ACM-ICPC的訓練及比賽,包括訓練札記、賽場風云、賽季縱橫、冠軍之路、崢嶸歲月。
《ACM國際大學生程序設計競賽(ACM-ICPC)系列叢書·ACM國際大學生程序設計競賽:算法與實現》適用于參加ACM國際大學生程序設計競賽的本科生和研究生,對參加青少年信息學奧林匹克競賽的中學生也很有指導價值。同時,作為程序設計、數據結構、算法等相關課程的拓展與提升,本叢書也是難得的教學輔助讀物。
寫在最前面的話
自從上海交通大學2002年第一次、2005年第二次獲得ACM國際大學生程序設計競賽(ACM International Collegiate Programming Contest,簡稱ACM-ICPC或ICPC)世界冠軍以來,總有記者邀請編者撰寫冠軍之路類的文章,也總有出版社希望編者出版ACM-ICPC競賽類的書籍,因為沒有想清楚怎么寫,所以一直沒動筆。直到2010年上海交通大學第三次獲得ACM-ICPC世界冠軍后,編者決定出版一套系列叢書,包括《ACM國際大學生程序設計競賽:知識與入門》、《ACM國際大學生程序設計競賽:算法與實現》、《ACM國際大學生程序設計競賽:題目與解讀》及《ACM國際大學生程序設計競賽:比賽與思考》4冊書籍,全面、深入而系統地將ACM-ICPC展現給讀者,把上海交通大學十多年來對ACM-ICPC競賽的感悟分享給讀者。
編寫此系列叢書的另一個重要原因是ACM-ICPC競賽在中國大陸的迅猛發(fā)展。自從1996年ACM-ICPC引入中國大陸,前六屆僅設立1個賽區(qū),目前每年一般設立5個賽區(qū),并已有30所高校承辦過亞洲區(qū)預賽;參賽學校從不滿20所,到如今已達200多所;參賽人數從不到100人,到如今超過12萬人次;總決賽名額從起初的3個,到如今已超過15個。同時,中國大陸在ACM-ICPC競賽上所取得的成績也舉世矚目。清華大學9次獲得總決賽獎牌(3金5銀1銅),位居獎牌榜之首,是實力最強、表現最穩(wěn)定的高校;上海交通大學8次獲得總決賽獎牌(4金3銀1銅),3次奪得世界冠軍,算是目前國內成績最好的高校;中山大學4次獲得總決賽獎牌(2銀2銅),在生源不占優(yōu)勢的情況下,這一成績令人敬佩;復旦大學3次獲得總決賽獎牌(1銀2銅),是公認的強校;浙江大學2次獲得總決賽獎牌(1金1銀),1次奪得世界冠軍,再次讓國人歡欣鼓舞;北京大學1次獲得總決賽獎牌(1銅),隊員的綜合實力堪稱一流;最難能可貴的是,華南理工大學也獲得過總決賽的獎牌(1銅),它告訴我們,ACM-ICPC不僅僅是“強!敝g的“對話”,只要堅持參與就會斬獲成果。另外,至今已有37所大陸高校參加過全球總決賽,且不論成績如何,他們在賽場上的奮斗亦值得稱道。
本系列叢書的第一冊《ACM國際大學生程序設計競賽:知識與入門》分為三個部分。知識點部分基本涵蓋了競賽中所涉及的主要知識點,包括數學基礎、數據結構、圖論、計算幾何、論題選編、求解策略等六個大類內容。入門與進階部分介紹了包括如何快速入門、如何提高自身以及團隊水平等,主要根據上海交通大學ACM-ICPC隊多年參賽經驗總結而來。在線資源部分對一些常用的在線評測系統和網上比賽進行了介紹。
本系列叢書的第二冊《ACM國際大學生程序設計競賽:算法與實現》涵蓋了大部分ACM-ICPC競賽常用的經典算法,包括數學、圖論、數據結構、計算幾何、論題選編五個大類,對每個算法的代碼實現,都配有接口說明以及簡略的算法闡述,并提供算法的完整程序,貼士部分收集了一些實用的知識點及積分表,方便讀者查找使用。
本系列叢書的第三冊《ACM國際大學生程序設計競賽:題目與解讀》分為兩個部分。例題精講部分針對第二冊《ACM國際大學生程序設計競賽:算法與實現》中的算法配備經典例題,并提供細致的解題思路,讀者可以通過這一部分學習和掌握算法;海量題庫部分按照算法分類羅列出大量習題,并提供相應的題解,讀者可以利用這一部分的題目進行訓練,更加熟練地運用各類算法。
本系列叢書的第四冊《ACM國際大學生程序設計競賽:?比賽與思考》從120多名隊員、2400余篇文檔中精心挑選、編纂而成的文集,包括訓練札記、賽場風云、賽季縱橫、冠軍之路、崢嶸歲月,集中展現了上海交通大學ACM-ICPC隊16年的奮斗歷程,記載了這些隊員為了實現自己的夢想而不懈努力、勇于拼搏的故事。
這是一套全面、系統地學習ACM-ICPC競賽的知識類書籍;
這是一套詳盡、深入地熟悉ACM-ICPC競賽的算法及題目的手冊類書籍;
這是一套程序設計、數據結構、算法等相關課程的拓展與提升類書籍;
這是一部上海交通大學ACM-ICPC隊的成長史;
這是一部激勵更多學子勇敢追尋并實現自己最初夢想的勵志書。
歷時2年零5個月,終于完成了本系列叢書,編者與隊員有一種如釋重負的感覺,因為我們把出版這套叢書看得很重,這是我們16年的經驗與積累,希望對廣大讀者有用。
值此ACM-ICPC進入中國大陸16周年、上海交通大學獲得ACM-ICPC世界冠軍10周年之際,謹以此系列叢書——
紀念我們曾經走過的路、度過的歲月;
獻給所有支持、幫助過我們的人……
俞 勇
2012年10月于上海
前 言
在ACM國際大學生程序設計競賽(ACM International Collegiate Programming Contest,ACM-ICPC或ICPC)中,實現算法的能力是非常重要的。尤其是對新手來說,在了解到一個新的算法后,有時會對如何實現該算法產生困惑,也許并不能一下想到很好的實現,這時就需要參考一些已有的實現。
另外,ACM-ICPC比賽中允許選手將一定量的(一般為25頁)紙質資料帶入比賽現場進行參考。隊伍往往會將一些相對較難實現的常用算法的代碼整理為SCL(Standard Code Library,標準代碼庫)帶入賽場,在需要的時候可以直接抄寫已有代碼,既節(jié)省時間,也保證了正確性。
因此我們出版這本收集了大量經典常用算法的用C++語言實現的代碼庫,希望可以幫助讀者學習算法以及準備比賽用的SCL。
本書分為兩個部分。第一部分為代碼庫,涵蓋了大部分比賽常用的經典算法,包括數學、圖論、數據結構、計算幾何、論題選編五個大類,對每個算法的代碼實現,都配有接口說明以及簡略的算法闡述,便于讀者理解。第二部分為貼士,收集了一些實用的知識點以及積分表,適合于帶入賽場進行參考。
本書編寫工作歷時兩年左右,參與編寫工作的人員全部為上海交通大學ACM-ICPC隊的現役隊員。代碼大多來自于往年上海交通大學ACM-ICPC隊使用的SCL以及隊員的日常訓練。同時,本書的編寫也得到上海交通大學ACM-ICPC隊的退役隊員大力幫助,他們參與了代碼庫的收集、整理、校驗等工作。
參與本書寫稿、審稿的人員主要有(按姓氏筆畫為序):?尹天蛟,烏辰洋,任春旭,劉奇,劉彥,壽鶴鳴,李說,楊思逸,吳卓杰,張捷鈞,陳明騁,陳澤佳,陳彬毅,陳爽,林承宇,金斌,鄭,胡張廣達,郭曉旭,曹雪智,康南茜,章雍哲,商靜波,彭上夫,譚天,繆沛晗,瞿鈞等。
在此,衷心感謝所有為此書出版做出直接或間接貢獻的人!也真心祝愿此書能夠在算法實現和SCL的準備上給讀者帶來幫助。
由于時間倉促,作者水平有限,疏漏、不當和不足之處在所難免,真誠地希望專家和讀者朋友們不吝賜教。如果您能在閱讀和使用此書過程中發(fā)現任何問題或有任何建議,懇請發(fā)郵件,我們將不勝感激。
編 者
2012年10月于上海
俞勇,1961年生于上海,現為上海交通大學教授、博士生導師。1986年畢業(yè)于華東師范大學計算機科學系,獲碩士學位。畢業(yè)后在上海交通大學任教至今。1996年至今擔任上海交通大學ACM國際大學生程序設計競賽領隊、主教練,3次率隊奪得ACM國際大學生程序設計競賽世界冠軍,上海交通大學成為該賽事亞洲第一個獲得冠軍、全球第三個“三冠王”的大學,2002、2012年相繼獲得“杰出教練獎”、“功勛教練獎”。
俞勇教授曾主編教材或著作4本、譯著3本,先后主持教育部教育教學改革項目2項,獲得國家級和上海市教學成果獎7項,上海市優(yōu)秀教材獎2項,并為國家精品課程“數據結構”、上海市“程序設計類基礎課程教學團隊”主持人。從事Web搜索與挖掘研究,先后主持國家自然科學基金、863計劃等十余項,發(fā)表重要國際會議和期刊學術論文百余篇。
俞勇教授曾獲得國務院特殊津貼、“全國師德標兵”、“寶鋼優(yōu)秀教師特等獎”、“上海市教學名師”、“上海市五一勞動獎章”、“上海市模范教師”、“上海交通大學校長獎”、“上海交通大學最受學生歡迎教師”、“上海交通大學最受研究生歡迎導師”等榮譽。曾被中央電視臺新聞聯播、上海教育臺、光明日報、文匯報等十多家媒體報道。
第一部分 算法
第1章 數學
1.1 矩陣
1.1.1 矩陣類
1.1.2 Gauss消元
1.1.3 矩陣的逆
1.1.4 常系數線性齊次遞推
1.2 整除與剩余
1.2.1 歐幾里得算法
1.2.2 擴展歐幾里得
1.2.3 單變元模線性方程
1.2.4 中國剩余定理
1.2.5 求原根
1.2.6 平方剩余
1.2.7 離散對數
1.2.8 N次剩余
1.3 素數與函數
1.3.1 素數篩法
1.3.2 素數判定
1.3.3 質因數分解
1.3.4 歐拉函數計算
1.3.5 Mobius函數計算
1.4 數值計算
1.4.1 數值積分
1.4.2 高階代數方程求根
1.5 其他
1.5.1 快速冪
1.5.2 進制轉換
1.5.3 格雷碼
1.5.4 高精度整數
1.5.5 快速傅立葉變換
1.5.6 分數類
1.5.7 全排列散列
第2章 圖論
2.1 圖的遍歷及連通性
2.1.1 前向星
2.1.2 割點和橋
2.1.3 雙連通分量
2.1.4 極大強連通分量Tarjan算法
2.1.5 拓撲排序
2.1.6 2SAT
2.2 路徑
2.2.1 Dijkstra
2.2.2 SPFA
2.2.3 Floyd-Warshall
2.2.4 無環(huán)圖最短路
2.2.5 第k短路
2.2.6 歐拉回路
2.2.7 混合圖歐拉回路
2.3 匹配
2.3.1 匈牙利算法
2.3.2 Hopcroft-Karp算法
2.3.3 KM算法
2.3.4 一般圖最大匹配
2.4 樹
2.4.1 LCA
2.4.2 最小生成樹Prim算法
2.4.3 最小生成樹Kruskal算法
2.4.4 單度限制最小生成樹
2.4.5 最小樹形圖
2.4.6 最優(yōu)比例生成樹
2.4.7 樹的直徑
2.5 網絡流
2.5.1 最大流Dinic算法
2.5.2 最小割
2.5.3 無向圖最小割
2.5.4 有上下界的網絡流
2.5.5 費用流
2.6 其他
2.6.1 完美消除序列
2.6.2 弦圖判定
2.6.3 最大團搜索算法
2.6.4 極大團的計數
2.6.5 圖的同構
2.6.6 樹的同構
第3章 計算幾何
3.1 多邊形
3.1.1 計算幾何誤差修正
3.1.2 計算幾何點類
3.1.3 計算幾何線段類
3.1.4 多邊形類
3.1.5 多邊形的重心
3.1.6 多邊形內格點數
3.1.7 凸多邊形類
3.1.8 凸多邊形的直徑
3.1.9 半平面切割多邊形
3.1.10 半平面交
3.1.11 凸多邊形交
3.1.12 多邊形的核
3.1.13 凸多邊形與直線集交
3.2 圓
3.2.1 圓與線求交
3.2.2 圓與多邊形交的面積
3.2.3 最小圓覆蓋
3.2.4 圓與圓求交
3.2.5 圓的離散化
3.2.6 圓的面積并
3.3 三維計算幾何
3.3.1 三維點類
3.3.2 三維直線類
3.3.3 三維平面類
3.3.4 三維向量旋轉
3.3.5 長方體表面兩點最短距離
3.3.6 四面體體積
3.3.7 最小球覆蓋
3.3.8 三維凸包
3.4 其他
3.4.1 三角形的四心
3.4.2 最近點對
3.4.3 平面最小曼哈頓距離生成樹
3.4.4 最大空凸包
3.4.5 平面劃分
第4章 數據結構
4.1 二叉堆
4.2 并查集
4.3 樹狀數組
4.4 左偏樹
4.5 Tne
4.6 Treap
4.7 伸展樹
4.8 RMQ線段樹
4.9 ST表
4.10 動態(tài)樹
4.11 塊狀鏈表
4.12 樹鏈剖分
第5章 論題選編
5.1 字符串
5.1.1 KMP
5.1.2 擴展KMP
5.1.3 串的最小表示
……
第二部分 貼士