Advanced Competitive Programming

Slides:



Advertisements
Similar presentations
如何學好數學? 黃駿耀老師
Advertisements

辅助核算 3.5.
10 郑和远航.
三个偶像的故事和功绩 ——第12课 明清时期的反侵略斗争 董飞燕.
捣蛋鬼历险记 初一四班 孙嘉佑小组.
中國歷史 明代之患禍及民變.
10 郑和远航 郑和 郑和,1371年生于云南昆阳州(今昆明晋宁县)一个信奉伊斯兰教的回族家庭,原名马和,小字三宝,十一岁时在明太祖朱元璋发动的统一云南的战争中被俘进宫,后当朱元璋四子燕王朱棣的近侍。1403年朱棣登基,史称明成祖。次年正月初一,朱棣念他有勇有谋,屡立奇功,便赐姓“郑”,改称郑和,并提拔为内宫太监,于永乐三年(1405年7月11日)率领庞大船队首次出使西洋。自1405年到1433年,漫长的28年间,郑和船队历经亚非三十余国,涉十万余里,与各国建立了政治,经济,文化的联系,完成了七下西洋的伟
明清 抗击外国侵略的英勇斗争 雅克萨反击战(俄) 戚继光抗倭(日) 郑成功收复台湾(荷兰) 荷兰 俄 罗 斯 日 本 台湾 沙 俄 入 侵
戚继光抗倭.
刑事訴訟法 授課人:林俊益副教授 時間:95.9.~96.6..
妩媚人生 云 计 算 与 大规模数据并行处理技术 黄 宜 华 南 京 大 学 计算机科学与技术系 软件新技术国家重点实验室 妩媚人生 妩媚人生
第16 课 中外的交往与冲突 授课人:鲍婷.
历史上的中日关系.
云南外事外语职业学院 入党积极分子培训 赵田甜.
第四章 清代臺灣的社會文化變遷 第一節 移墾社會的形成
認識食品中毒 一、什麼是食品中毒? 二人或二人以上攝取相同的食品而發生相似的症狀,並且自可疑的食餘檢體及患者糞便、嘔吐物、血液等人體檢體,或者其它有關環境檢體(如空氣、水、土壤等)中分離出相同類型(如血清型、噬菌 體型)的致病原因,則稱為一件“食品中毒”。 但如因攝食肉毒桿菌毒素或急性化學性中毒而引起死亡,即使只有一人,也視為一件“食品中毒”。
題目:四大古文明 班級:六年八 班 組員:賴宣光.游家齊.陳羿文 吳佳芬.許淑婷.許芳瑜..
食 物 中 毒.
琦君 《髻》 S 康倩瑜.
眼乾乾唔使慌.
滑膜皱襞综合征.
“公平”是最热的关键词 1、胡锦涛首次进行“总动员”,提出“在促进发展的同时,把维护社会公平放到更加突出的位置” 。
贵州省公务员面试 备考指导 中公教育 面试讲师 刘运龙.
外 套 各式領型與變化 武 玫 莉 製 作.
第4节 人体对食物的消化吸收.
陈冤之魅,心鬼之泪 ——雾里探花 《东方快车谋杀案》 By第二小组.
高考作文等级评分标准/发展等级10分 深刻 丰富 有文采 有创意 ①透过现象 深入本质 ②揭示问题 产生的原因 ③观点具有 启发作用
文明礼仪在我心 文明礼仪在我心.
第10课 社会生活的变迁.
故事会 盘古开天劈地 在很久很久以前,天地可不象我们现在看到的这样————天高高的在上面,地在我们的脚下,中间隔着几千几万米远。那个时候的天地就象是一个包在大黑壳里的鸡蛋,混混沌沌的,什么也看不清。人们走路都得弯着腰,耕田打猎都很不方便,因为一不小心抬个头,就会碰到天,惹它生气,接着就会招来狂风暴雨。因此所有的植物也都长不高,所以结的粮食和果实都很少,根本就不够大家吃。还经常会发生饿死人的事情。
面向三农,拓宽信息渠道 辐射千村,服务百万农民
三招 让孩子爱上阅读 主讲人:芝莺妈妈 2012年10月19日.
FUZHUANGZHITUYANGBANZHIZUO
如何挑選吳郭魚 嗨~ 餐旅二乙 4a2m0105 白妤潔 4a2m0122 何姿瑩.
学校春季呼吸道传染病预防知识 连云港市疾病预防控制中心
服裝整理概論.
印染纺织类艺术.
创业计划书的编写.
创业计划书撰写.
第九章 进行充分调研 选择自主创业.
香溢饺子馆创业计划书.
第三章 中国的民族民俗 第一节 概论 第二节 汉族 第三节 满族 蒙古族 维吾尔族 回族 朝鲜族 第四节 壮族 土家族 苗族 黎族
第 4 章 投资银行: 基于资本市场的主业架构.
创业数字图书馆.
中国管理科学发展探索 成思危 2006年8月18日于上海复旦大学.
“四文”交融,虚实并举,打造具有鲜明职教特色的校园文化 ——江苏省扬州商务高等职业学校校园文化建设汇报
103年度高職優質化輔助方案計畫申辦及輔導訪視說明會
“十二五”科技发展思路 与科技计划管理 科技部发展计划司 刘敏 2012年9月.
社区妇幼保健工作 江东区妇幼保健院 胡波瑛.
人生不要太圓滿 ◎ 張忠謀.
导致羊水过少的五大因素.
胎教.
怎样进行一次宣讲 何惠玲.
第三课 中国共产党的历程.
[聚會時,請將傳呼機和手提電話關掉,多謝合作]
规范母婴保健服务 努力降低孕产妇死亡率 市卫生局基妇科 朱静.
中国地质科学院矿产资源研究所 财务报账培训
白天的月亮 想與日爭輝 人生不要太圓滿 文字取自於:張忠謀 攝於陽明山 阿道的攝影工作坊.
第十章(上) 实现中华民族的伟大复兴.
营养要均衡.
ㄩ.
高中新课程历史必修(Ⅰ) 教材比较研究 四川师范大学历史文化学院教授 陈 辉 教育部2009普通高中历史课改远程研修资料.
十年职业生涯规划 —— 年 姓名:刘娟 学号:.
主考官眼中的面试 ——面试主考官教你备战2016年国考面试 主讲老师:李海鹏.
国内知名高校 医学院(部、中心) 院系及附属医院设置情况 调研报告
財務報表分析 授課教師:陳依婷.
第六章 可供出售金融资产 一、可供出售金融资产的概念和特征 二、可供出售金融资产的核算.
主讲人:刘文波 (四会国税 政策法规股) 2014年4月
智慧宁波 智慧财税 . 宁波市地方税务局.
第六模块礼仪文书写作 第一节求职信、应聘信 QIUZHIXINYINGPINXIN.
Presentation transcript:

Advanced Competitive Programming 國立成功大學ACM-ICPC程式競賽培訓隊 nckuacm@imslab.org Department of Computer Science and Information Engineering National Cheng Kung University Tainan, Taiwan

Number Theory

Number Theory Prime Generation Integer Factorization

Number Theory Prime Generation Integer Factorization

埃拉托斯特尼篩法 Sieve of Eratosthenes 簡稱「篩法」 這是一個製作質數表的演算法。 時間複雜度 O(NloglogN)

埃拉托斯特尼篩法 Sieve of Eratosthenes

埃拉托斯特尼篩法 Sieve of Eratosthenes 列出所有正整數。 從 2 開始,刪掉 2 的倍數。 找下一個未被刪掉的數字,找到 3 ,刪掉 3 的倍數。 找下一個未被刪掉的數字,找到 5 ,刪掉 5 的倍數。 如此不斷下去,就能刪掉所有合數,找到所有質數。

埃拉托斯特尼篩法 Sieve of Eratosthenes bool sieve[20000000]; void eratosthenes() { sieve[0] = sieve[1] = true; // 0 和 1 不是質數 for (int i = 2; i < 20000000; i++) if (!sieve[i]) // 找下一個未被刪掉的數字 for (int j = i + i; j < 20000000; j += i) sieve[j] = true; // 刪掉質數 i 的倍數 }

埃拉托斯特尼篩法 Sieve of Eratosthenes 欲刪掉質數 i 的倍數之時,早已刪掉其 2 倍到 i-1 倍了,所以可以直接從 i 倍開始。 一個合數 n ,必定有一個小於等於 sqrt(n) 的質因 數。 所有小於等於 sqrt(n) 的質數,刪掉這些質數的倍 數,就能刪掉所有合數了,剩下沒刪掉的都是質數

埃拉托斯特尼篩法 Sieve of Eratosthenes bool sieve[20000000]; void eratosthenes() { sieve[0] = sieve[1] = true; for (int i = 2; i * i < 20000000; i++) // 以平方代替根號計算,以避免小數造成誤差 if (!sieve[i]) for (int j = i * i; j < 20000000; j += i) sieve[j] = true; }

線性時間篩法 Linear Sieve Algorithm 一邊製作質數表,一邊刪掉每個數的質數倍, 如此每個合數就只讀取一次,時間複雜度達到 O(N) 。

線性時間篩法 Linear Sieve Algorithm const int N = 20000000; bool sieve[N]; void linear_sieve() { vector<int> prime; for (int i = 2; i < N; i++) { if (!sieve[i]) prime.push_back(i); for (int j = 0; i * prime[j] < N; j++) { sieve[i * prime[j]] = true; if (i % prime[j] == 0) break; }

Questions?

練習 UVa OJ 406 UVa OJ 543 UVa OJ 10140 UVa OJ 10311

Number Theory Prime Generation Integer Factorization

質因數分解 把一個正整數分解成質因數的連乘積。 n = 2^n₁ × 3^n₂ × 5^n₃ × 7^n₄ × 11^n₅ × …

質因數分解 把所有可能的因數拿來試除。 void trial_division(int n) { for(int d = 2; d <= n; ++d) while(n % d == 0) { n /= d; cout << d; // 質因數 }

質因數分解 跟篩質數時一樣檢查小於等於sqrt(n)的因數就好了 void trial_division(int n) { for(int d = 2; d * d <= n; ++d) while(n % d == 0) { n /= d; cout << d; // 質因數 } if(n > 1) cout << n; // n是質數

質因數分解 質因數必定是質數 所以只要建好質數表 然後試除小於sqrt(n)的質數就好了

Questions?

練習 UVa OJ 583 UVa OJ 10392 UVa OJ 10622 UVa OJ 10791 UVa OJ 10879

Calculation

Calculation 對於大數字的運算,普通的做法不夠快, 因此接下來將介紹快速的乘法及冪運算

Calculation Gauss′s complex multiplication algorithm Karatsuba algorithm Fast exponentiation

Calculation Gauss′s complex multiplication algorithm Karatsuba algorithm Fast exponentiation

複數乘法 對於 a + bi, c + di

複數乘法 對於 a + bi, c + di 相乘得 (ac – bd) + (bc + ad)i

複數乘法 對於 a + bi, c + di 相乘得 (ac – bd) + (bc + ad)i 一般需要計算 ac, bd, bc, ad 共四次乘法 才能計算出兩數相乘

複數乘法 (ac – bd) + (bc + ad)i 對於 (ac – bd) = ac + bc – bc – bd

複數乘法 (ac – bd) + (bc + ad)i 對於 (ac – bd) = ac + bc – bc – bd 令 k1 = ac + bc = c(a+b) k2 = bc + bd = b(c+d)

複數乘法 (ac – bd) + (bc + ad)i 對於 (bc + ad) = ac + bc + ad – ac

複數乘法 (ac – bd) + (bc + ad)i 對於 (bc + ad) = ac + bc + ad – ac 令 k1 = ac + bc = c(a+b) k3 = ad - ac = a(d-c)

複數乘法 (ac – bd) + (bc + ad)i = (k1-k2) + (k1+k3)i k1 = ac + bc = c(a+b) k2 = bc + bd = b(c+d) k3 = ad - ac = a(d-c)

複數乘法 (ac – bd) + (bc + ad)i = (k1-k2) + (k1+k3)i 總共只需要三次乘法 似乎變快了一點

Questions?

Calculation Gauss′s complex multiplication algorithm Karatsuba algorithm Fast exponentiation

Karatsuba algorithm 對於剛剛的複數乘法 似乎對於整數 x, y 相乘有些啟示

Karatsuba algorithm 對於剛剛的複數乘法 似乎對於整數 x, y 相乘有些啟示 也就是令 x = am + b y = cm + d a + bi

x = am + b y = cm + d xy = acm2 + (ad + bc)m + bd Karatsuba algorithm x = am + b y = cm + d xy = acm2 + (ad + bc)m + bd

Karatsuba algorithm xy = acm2 + (ad + bc)m + bd 其中 (ad + bc) = ad + ac + bc + bd – bd – ac = (a + b)(c + d) – bd - ac

Karatsuba algorithm xy = acm2 + (ad + bc)m + bd (ad + bc) = ad + ac + bc + bd – bd – ac = (a + b)(c + d) – bd – ac z1 = ac z2 = bd z3 = (a + b)(c + d)

Karatsuba algorithm xy = acm2 + (ad + bc)m + bd 也就是說 xy = z1m2 + (z3-z1-z2)m + z2 z1 = ac z2 = bd z3 = (a + b)(c + d)

Karatsuba algorithm xy = acm2 + (ad + bc)m + bd 也就是說 xy = z1m2 + (z3-z1-z2)m + z2 z1 = ac z2 = bd z3 = (a + b)(c + d)

Karatsuba algorithm xy = z1m2 + (z3-z1-z2)m + z2 假設數字長度為 n 總共只需要三次乘法 相較於直式乘法複雜度 O(n2) 這個算法有複雜度 3⋅O(n2)

Karatsuba algorithm 到底在幹三小?

分治法 對於上述演算法, 凡是遇到乘法運算,都使用同樣的演算法 感恩分治 讚嘆分治

分治法 對於上述演算法, 凡是遇到乘法運算,都使用同樣的演算法 並且對於數字的分割,總是分成均等的兩半 例如 6789 分成 67 和 89 6789 = 67⋅100 + 89

分治法 int k(int x, int y) { if(x < 10 || y < 10) return x*y; int len = min(log10(x), log10(y)); int m = pow(10, len/2 + 1); auto [a, b] = div(x, m); // since c++17 auto [c, d] = div(y, m); int z1 = k(a, c), z2 = k(b, d), z3 = k(a+b, c+d); return z1*m*m + (z3-z1-z2)*m + z2; }

分治法 時間成本 T(n) T(n) = 3⋅T(n/2) + cn T(1) = 1 + c1 複雜度為 O(3lgn) = O(nlg3)

Questions?

Calculation Gauss′s complex multiplication algorithm Karatsuba algorithm Fast exponentiation

Exponentiating by Squaring 快速冪以及矩陣快速冪

如何計算 3987654321 % 1000007 O(n):反正就把 3 一直乘 O(lg n):快速冪

快速冪 觀察 3n × 3n = 32n 可以分解3987654321 = 31 × 316 × 332 × 3128 × …… = 111010110111100110100010110001(2)// 抱歉很亂 = 1 + 16 + 32 + 128 + …

快速冪 只要 n 是 2 的冪次 3n 就能很快求出來 3n = 3n/2 × 3n/2

快速冪 int x = 1, a = 3; while (n) { } // x 就是答案 if (n&1) x *= a; // 二進位尾數是 1 x %= 1000007; a *= a; a %= 1000007; n >>= 1; } // x 就是答案

矩陣快速冪 矩陣也有類似性質 假設現在有個方陣 A,An × An = A2n 對於費氏數列:

練習 Zero Judge b525 b525: 先別管這個了,你聽過turtlebee嗎?

Questions?

Floating-Point Precision 浮點數誤差以及競程處理技巧

形成原因:IEEE 754 的浮點數的儲存 用 0 跟 1 表示浮點數 表示方式:1.1101010(2) × 24(10) 優點:在精度內可以表達好,通常精度夠用 缺點:超出精度就無法表示 直接 WA

舉例 0.69(double) × 10 ≠ 6.9 (double) 結果可能是 6.89999…… 在 print 的時候不容易出錯,但在比較大小或判 斷相等時常會出問題

解決方法 假設今天有個閾值是 6.9,6.899999 這樣的表 示會有問題 解決方案一:四捨五入 解決方案二:乘上 1.000…001(數量根據精度調整) -> 較推薦

解決方法(比較大小) if (0.69 * 10 * 1.000…1 >= 6.9) { do something }

解決方法(比較相等) if (abs((0.69*10) - 6.9) <= 0.69*1e-15) { do something }

AC Get