Re: [問題] 大數如何遞減?

看板C_and_CPP (C/C++)作者 (卡卡獸)時間13年前 (2013/01/22 09:00), 編輯推噓8(8018)
留言26則, 9人參與, 最新討論串2/3 (看更多)
※ 引述《luke90512 (阿神)》之銘言: : input為一系列的整數,範圍是1~2*10^100 : 對每個input假設為n : 計算s=1^1+2^2+3^3+...+n^n : 只取s的個位數作為答案 : 程式碼(Code):(請善用置底文網頁, 記得排版) : http://ideone.com/BQz0Uz 其他恕刪,我看你後來改的 code 還是有用到 pow 函式 (恕我沒細看理解), 然後早上起床想了一下,做了一點推導可以參考一下。 數學表達不好,見諒,另我也不保證這想法是可 AC 的。 --- 首先在意的是 1^1, 11^11, 21^21 尾數是多少; 再來在意的是 2^2, 12^12, 22^22 尾數是多少; 然後發現其實有規律可詢, 像 2^2 尾數是 4 ; 12^12 尾數是 6; 22^22 尾數是 4 ;32^32 尾數是 6... ; 依此類推,經過一點推導後結論如下 (可能有推錯,不過目前驗證是對的) --- n/10=even, n=10=odd, n/10=even ----------------------------- 0 : 尾數必為 0 (0^0= 0, 10^10=..0, 20^20=..0) 1 : 尾數必為 1 (1^1= 1, 11^11=..1, 21^21=..1) 2 : 尾數變化 4 -> 6 -> 4 -> 6 -> ... (2^2= 4, 12^12=..6, 22^22=..4) 3 : 尾數變數 7 -> 3 -> 7 -> 3 -> ... (3^3=..7, 13^13=..3, 23^23=..7) 4 : 尾數必為 6 (4^4=..6, 14^14=..6, 24^24=..6) 5 : 尾數必為 5 (5^5= 5, 15^15=..5, 25^25=..5) 6 : 尾數必為 6 (6^6= 6, 16^16=..6, 26^26=..6) 7 : 尾數變化 3 -> 7 -> 3 -> 7 -> .... (7^7=..3, 17^17=..7, 27^27=..3) 8 : 尾數變化 6 -> 4 -> 6 -> 4 -> .... (8^8=..6, 18^18=..4, 28^28=..6) 9 : 尾數必為 9 (9^9=..9, 19^19=..9, 29^29=..9) --- 上面如果會看的話,可以做很多事了,拿簡單的例子來講, 如果是算 1^1 + .... + 10^10 ,取變化的第一個數字 (像2的話就是 4,3的話是 7) 1^1 + .... + 10^10 = 1 + 4 + 7 + 6 + 5 + 6 + 3 + 6 + 9 + 0= 47,尾數=7 然後注意到,其實 10^10 有沒有加是無所謂、不影響結果的。 如果是算 11^11 + .... + 20^20 ,取變化的第二個數字 ( 2的話取 6,3的話取 3) 11^11 + .... + 20^20 = 1 + 6 + 3 + 6 + 5 + 6 + 7 + 4 + 9 + 0 = 47,尾數=7 再推廣下去的話,會變成, 1+.....+10^10 -> 47 ---> 尾數 7 1+.....+20^20 = (1+....+10^10) + (11^11 +....+20^20) -> (7 + 7) = 14 -> 尾數 4 1+.....+30^30 -> 7+7+7 = 21 --> 1 1+.....+40^40 -> 7*4 = 28 --> 8 1+.....+50^50 -> 7*5 = 35 --> 5 換句話說,如果 n 是 10 的倍數,或是10的倍數減 1, 那尾數就變成了.. ( (n+1) / 10 ) * 7 % 10 然後接下來的剩下不是 n 的部份怎麼做呢?回到最上面一開始給你的規則, 去建表相加。 ------------ 再來是,上面的 1+....+10^10 , 1+....+20^20,是以 10 為 gap ,但其實有更好的 規則,是 gap 一次考慮 20 個,你會發現如下 1+....+20^20 ---> 尾數 = 4 1+....+40^40 ---> 尾數 = 8 1+....+80^80 ---> 尾數 = 2 1+....+100^100 ---> 尾數 = 0 1+....+120^120 ---> 尾數 = 4 ----> 這裡開始循環 8 2 0 ... 上面這些可以建表。 有些超過題目太多就不說了,假設題目是給你 1+...+88^88 的話... (1) 1+...+80^80 --> 尾數 = 2 < 從 n gap 20 規則取得, O(1) > (2) 81^81 + ....+ 88^88 ,從最一開始給你的規則判斷, ---> 1 + 4 + 7 + 6 + 5 + 6 + 3 + 6 = 38 --> 尾數 = 8 最後得到 2+8 = 10,10%10 = 0, 這就是結果了。 在第二步要加快速度的話我會建立一個表,大概長這樣 int times_20[] = {0,1,4,7,6,5,6,3,6,9, // 00~09, 20~29, 40~49 尾數 0,1,6,3,6,5,6,7,4,9}; // 10~19, 30~39, 50~59 尾數 int column_times[20]; column_times[0] = times_20[0]; for(i=1; i<20; ++i) column_times[i] = column_times[i-1] + times_20[i]; 上面的 column_times 事先算好,然後第二步就可以就可用 column_times 去做,O(1), 於是整體的效能反而落在,大數(n) 除以 整數(20) / 大數(n) Mod 整數 (20), 上面的 除以20 和 Mod20,是同一個副函式可做出來的東西。 --- 這可能不是最快的, implement 沒太大興趣,希望有給您一點靈感。 -- ~ 這輩子與神手無緣 我只好當神獸了 ~ 卡卡獸 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 180.177.76.161

01/22 09:35, , 1F
讚...程式只是工具, 重點是你怎麼解問題
01/22 09:35, 1F

01/22 09:56, , 2F
想了一下,最後的 /20 , %20 還有機會偷工,不過我懶了 XD
01/22 09:56, 2F

01/22 10:52, , 3F
也可以先算 1^1+...+n^n % 5 還有 1^1+...+n^n%2 再用 CRT
01/22 10:52, 3F

01/22 10:56, , 4F
(i^i)%2 是兩個一循環,(i^i)%5 是 20 個一循環
01/22 10:56, 4F

01/22 11:08, , 5F
s 大方法漂亮, 不過「算落在哪個循環」似乎還是要大數除 ?
01/22 11:08, 5F

01/22 11:36, , 6F
20個一循環 所以100個也會循環 吧?
01/22 11:36, 6F

01/22 11:37, , 7F
(i^i)%5 可以從 (i^(i%4))%5 來看 大概是 20 的由來?
01/22 11:37, 7F

01/22 11:42, , 8F
n%20 應該不能算是大數除吧 XD ,只要看最後兩位就好了
01/22 11:42, 8F

01/22 11:57, , 9F
熊熊腦鈍, 確實拿最後兩位數, 配合 CRT 就出來了, 謝謝 :)
01/22 11:57, 9F

01/22 12:29, , 10F
感謝Ed大還有各位~ 看來頭腦要再靈活一點了!
01/22 12:29, 10F

01/22 13:52, , 11F
推一下, 我還沒想到底.
01/22 13:52, 11F

01/22 13:54, , 12F
推e大 推人超好~
01/22 13:54, 12F

01/22 15:53, , 13F
請問一下CRT是什麼呢?
01/22 15:53, 13F

01/22 16:03, , 14F
chinese remainder theorem
01/22 16:03, 14F

01/22 16:03, , 15F
中國剩餘定理
01/22 16:03, 15F

01/22 17:41, , 16F
((n-1)/10)*7%10 那邊應該是n+1 因為19^19跟20^20的結果一樣
01/22 17:41, 16F

01/22 17:42, , 17F
然後一次考慮20個那邊第一行應該是 1+....+20^20才對
01/22 17:42, 17F
謝謝 D 大指正 :) ※ 編輯: EdisonX 來自: 180.177.76.161 (01/22 17:57)

01/22 18:09, , 18F
sum(i^i)的個位數每180個一循環,所以只要算(i^i)%180
01/22 18:09, 18F

01/22 18:40, , 19F
有人可以解釋一下推文的循環都怎麼出來的嗎?
01/22 18:40, 19F

01/22 18:59, , 20F
(i^i)%180,這個要配大數的話大概沒辦法吧? 10^n/180 不會
01/22 18:59, 20F

01/22 19:01, , 21F
是整數吧
01/22 19:01, 21F

01/22 19:04, , 22F
費馬小定理 x^(p-1)%p=1 若p是質數,所以i^i%5=i^(i%4)%5
01/22 19:04, 22F

01/22 19:05, , 23F
所以最多 5*4 個就會循環
01/22 19:05, 23F

01/22 19:05, , 24F
而 (1^1+...+n^n)%5 最多只要再 5 倍,也就是 100 個一循環
01/22 19:05, 24F

01/22 19:05, , 25F
< 小聲的說,數學不好其實可以先寫一份簡易大數,用暴力觀查
01/22 19:05, 25F

01/22 19:06, , 26F
多暴力呢? 就和 分數化循環小數 不用數學解 一樣暴力 >
01/22 19:06, 26F
文章代碼(AID): #1G_UImTx (C_and_CPP)
討論串 (同標題文章)
本文引述了以下文章的的內容:
完整討論串 (本文為第 2 之 3 篇):
文章代碼(AID): #1G_UImTx (C_and_CPP)