※前言
關於質數,台灣競賽方面似乎比較少提及,頂多學學篩法、根號檢驗法而已。
草提一下這兩個算法:
>>埃氏篩法:
//什麼毛啦顏色傳上來變得醜死了
O(N ln N)時間複雜度、O(N)記憶體,求出1~N所有的質數。
一些優化:
1. 僅 型如 6n ± 1 者有可能是質數(2 | 6n+2、3 | 6n+3、2 | 6n+4)
其實這個優化加下去已經可以達到一定速度了。
2. 用位元壓縮,記憶體僅需要(N/32)個int(排掉偶數可以剩下N/64,但個人認為沒必要)
一些應用:
1. 求出質因數個數:
值得注意的是I = i*i要改成I = i+i才行。
2. 求Φ(n):
即找出1~n-1中有幾個跟n互質的數。
因為有Φ(n) = n * Π(1 - (1/p)) 對每個質數p | n,所以可以用篩法作到。
// 另外,線性篩法我不會,所以省略...
相關題目:
TIOJ:1036、1260、1353、1514、1535
ACM:294
>>根號檢驗法:
O(√n)檢驗一個數是否為質數。
一些應用:
1. 質因數分解:
每次除到不能除,若<= √p都試完了剩下的那個一定是質數。
相關題目:
ACM:583
反正目前為止的台灣競賽幾乎都只注重以上兩者,相關題目也十分罕見(目前為止沒見過)
但是對於密碼學而言,以上算法都還不能讓人滿意。
>>Miller-Rabin:
一個能期望極快的判斷質數作法。
算法核心:
引理一:若p是質數,則a(p-1) mod p = 1 (費瑪小定理)
引理二:若x2 mod p = 1(其中x<p、p是質數)那x = p-1或x = 1 (證明就是用(x+1)(x-1) = kp)
然後若我們要測定n是否能通過以a為底的米勒拉賓測試
先把n-1 = 2r * d , 其中d是奇數 也就是求出n-1最高含2的幾次方
那麼 如果 a (2r * d) mod n 不是1 就一定是合數 (引理一)
就繼續下去a (2(r-1) * d) mod n 得是n-1 或1(引理二)
如果是n-1即是通過檢測,如果是1就繼續遞迴直到 ad mod n
對int範圍的數字,只需要測 a = 2, 7, 61
對10^16內的數字,只需要測 a = 2, 3, 5, 7, 11, 13, 17, 61, 24251
所以只需要寫一個大數次方 + 主程序大概 20~30 行很OK。
虛擬碼就不附了,上次寫得爛爛的。
進一步可以參照Matrix67的相關文章。
>>Pollard-ρ:
還在學...
2010年9月12日 星期日
2010年9月10日 星期五
PKU 1286 Necklace of Beads [Pólya]
poao899 1286 Accepted 404K 0MS G++ 416B 2010-09-10 23:20:57 .
Pólya超經典題。
長為n<24的項鍊,三種顏色定義不同構為旋轉 翻轉<b>擇一</b>後不一樣者。
就套Pólya:
( Σ(i=1...n)(3^gcd(i, n)) + 翻轉 ) / 2n
反正學過真的就水過。
Pólya超經典題。
長為n<24的項鍊,三種顏色定義不同構為旋轉 翻轉<b>擇一</b>後不一樣者。
就套Pólya:
( Σ(i=1...n)(3^gcd(i, n)) + 翻轉 ) / 2n
反正學過真的就水過。
2010年9月5日 星期日
NTUJ 1021 Highway Patrol
36916 1021 - Highway Patrol poao899 Accepted C++ 0.030 2010-09-05 19:41:21 .
好題欸@@
題意:
一個大都會內有N座城市(<=100),有M條單行道(<=1,000)
每個單行道可以用一個數組(u, v, p, s, x)表示,表示有一條道路從u往v,
如果要派軍隊巡邏要花費p的代價、裝監視器要s的代價 (0 <= p,s <= 1,000,000)
x代表這條道路的重要性,1表示極為重要,不可以用監視器。
因為這個大都會治安很差,每條道路都必須選擇上述兩種方式之一維持治安品質。
但是,每個軍隊巡邏完了要能回到自己的城市休息,所以我們希望每個城市出分枝度 == 入分枝度。
而且,市民們也不希望看到一個全部僅由監視器戍守的城市,所以至少得有一條路是巡邏。
問最少需要花多少錢滿足以上要求。
Input:
第一行有一個數字T表示測資筆數(T <= 70)
每筆測資第一行是N, M,接下來M行每行有五個數字u, v, p, s, x。
Output:
第i筆測資輸出Case [i]: [cost]
[i]表示測資筆數,[cost]表示你所花的錢,無解請用"impossible取代"。
Sample input:
3
4 5
1 2 10 25 0
2 3 10 5 0
3 1 10 5 0
2 4 10 5 0
4 3 30 5 0
4 5
1 2 10 25 0
2 3 10 5 0
3 1 10 5 0
2 4 10 5 0
4 3 30 5 1
2 1
1 2 10 25 1
Sample output:
Case 1: 40
Case 2: 65
Case 3: impossible
=================Solution================
簡單的先捏一下,flow。
因為把這個問題轉化一下可以想到,你可以假設一開始全部監視,那這樣總cost是Σ(si)。
然後每把一個邊變成巡邏的cost會是(pi-si)。
而且最後答案一定巡邏的邊會形成好幾個環。
所以就一直找全局最小環加上去,加到那個環是正的為止。
進一步會發現,變成有負圈的圖形每次尋找全局最小簡單環。不過很可惜這個題目沒多項式作法。
所以要換一個想法。
可以先把p便宜的邊先巡邏、s便宜的邊先監視。
然後建起來可替換邊以及他的替換代價,容量都是1
然後對每個點,檢查有幾個巡邏出發/幾個巡邏回來 其中的相差就建到S/E,cost=0,容量是差。
作一次帶權flow,算出答案...
然後還要檢查答案是否合法:如果==Σ(si)那就表示你一個邊都沒取
所以Warshall一次,找出最小圈輸出
好題欸@@
題意:
一個大都會內有N座城市(<=100),有M條單行道(<=1,000)
每個單行道可以用一個數組(u, v, p, s, x)表示,表示有一條道路從u往v,
如果要派軍隊巡邏要花費p的代價、裝監視器要s的代價 (0 <= p,s <= 1,000,000)
x代表這條道路的重要性,1表示極為重要,不可以用監視器。
因為這個大都會治安很差,每條道路都必須選擇上述兩種方式之一維持治安品質。
但是,每個軍隊巡邏完了要能回到自己的城市休息,所以我們希望每個城市出分枝度 == 入分枝度。
而且,市民們也不希望看到一個全部僅由監視器戍守的城市,所以至少得有一條路是巡邏。
問最少需要花多少錢滿足以上要求。
Input:
第一行有一個數字T表示測資筆數(T <= 70)
每筆測資第一行是N, M,接下來M行每行有五個數字u, v, p, s, x。
Output:
第i筆測資輸出Case [i]: [cost]
[i]表示測資筆數,[cost]表示你所花的錢,無解請用"impossible取代"。
Sample input:
3
4 5
1 2 10 25 0
2 3 10 5 0
3 1 10 5 0
2 4 10 5 0
4 3 30 5 0
4 5
1 2 10 25 0
2 3 10 5 0
3 1 10 5 0
2 4 10 5 0
4 3 30 5 1
2 1
1 2 10 25 1
Sample output:
Case 1: 40
Case 2: 65
Case 3: impossible
=================Solution================
簡單的先捏一下,flow。
因為把這個問題轉化一下可以想到,你可以假設一開始全部監視,那這樣總cost是Σ(si)。
然後每把一個邊變成巡邏的cost會是(pi-si)。
而且最後答案一定巡邏的邊會形成好幾個環。
所以就一直找全局最小環加上去,加到那個環是正的為止。
進一步會發現,變成有負圈的圖形每次尋找全局最小簡單環。不過很可惜這個題目沒多項式作法。
所以要換一個想法。
可以先把p便宜的邊先巡邏、s便宜的邊先監視。
然後建起來可替換邊以及他的替換代價,容量都是1
然後對每個點,檢查有幾個巡邏出發/幾個巡邏回來 其中的相差就建到S/E,cost=0,容量是差。
作一次帶權flow,算出答案...
然後還要檢查答案是否合法:如果==Σ(si)那就表示你一個邊都沒取
所以Warshall一次,找出最小圈輸出
2010年9月2日 星期四
PKU 2540 Hotter Colder [CG]
7564334 poao899 2540 Accepted 424K 0MS G++ 3998B 2010-09-02 22:09:01 .
CG題好硬QQ不過應該是打定了XD寫起來頗有成就感(?)
看那精美的code length(望
不過 看到這題還是會想到IOI那個吧XD
題目大意:
有個房間,大小10*10
你一開始站在(0,0),某個位置有一個熱源。
接下來每次你會移動到任意一個座標,然後會告訴你感覺Hotter還是Colder還是Same
每次移動輸出一個數字表示 "熱源可能位置" 的面積。
保證不會移動超過50次。
Sample Input:
10.0 10.0 Colder
10.0 0.0 Hotter
0.0 0.0 Colder
10.0 10.0 Hotter
Sample Output:
50.00
37.50
12.50
0.00
===============解題報告===============
等於每次對多邊形切一條線,問面積。
測資很小所以可以每次把所有點掃過一遍。
幾個要注意的地方:
1. 判斷交點要注意等於0的狀況= =
2. 把兩個交點去修正多邊形時要注意加入的順序。
3. 注意如果重複點加入多邊形,會爆炸。
大概差不多這樣吧xD
CG題好硬QQ不過應該是打定了XD寫起來頗有成就感(?)
看那精美的code length(望
不過 看到這題還是會想到IOI那個吧XD
題目大意:
有個房間,大小10*10
你一開始站在(0,0),某個位置有一個熱源。
接下來每次你會移動到任意一個座標,然後會告訴你感覺Hotter還是Colder還是Same
每次移動輸出一個數字表示 "熱源可能位置" 的面積。
保證不會移動超過50次。
Sample Input:
10.0 10.0 Colder
10.0 0.0 Hotter
0.0 0.0 Colder
10.0 10.0 Hotter
Sample Output:
50.00
37.50
12.50
0.00
===============解題報告===============
等於每次對多邊形切一條線,問面積。
測資很小所以可以每次把所有點掃過一遍。
幾個要注意的地方:
1. 判斷交點要注意等於0的狀況= =
2. 把兩個交點去修正多邊形時要注意加入的順序。
3. 注意如果重複點加入多邊形,會爆炸。
大概差不多這樣吧xD
訂閱:
文章 (Atom)