1. 程式人生 > >題解 CF327C 【Magic Five】

題解 CF327C 【Magic Five】

這道題帶坑,假如沒有發現肯定會爆。

首先先搜尋一遍0和5,儲存在陣列a裡面。

那麼應當有2 ^ a1 +2 ^ a2 +...+ 2 ^ an。

然而這道題沒那麼簡單,數串還可以重複k次。

因此,需要在此基礎上在乘上1 + 2 ^ l + 2 ^ 2l +...+ 2 ^ (k - 1)l。其中l為數串長度。

如果到這裡就提交,那就只能和AC說拜拜了。

為了省去不必要的計算,可以通過等比數列求和公式將後一個算式化簡為(2 ^ kl - 1) / (2 ^ l - 1)

可即便如此還是會炸,只能藉助費馬小定理:a ^ (p-1) % p == 1。

所以算式可以進一步化簡為(2 ^ kl - 1) * (a ^ (l - 1) ^ (p-2)) / (2 ^ l - 1)

然後快速冪就OK了。

AC程式碼如下:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 using namespace std;
 6 
 7 const int MODE = 1000000007;
 8 const int maxn = 100100;
 9 typedef long long ll;
10 
11 ll power(ll a, ll n) {
12     ll b = 1;
13     while
(n) { 14 if(n & 1) { 15 b *= a; 16 b %= MODE; 17 } 18 n >>= 1; 19 a *= a; 20 a %= MODE; 21 } 22 return b; 23 } 24 25 ll k, ans, cur; 26 string num; 27 28 int main() { 29 cin >> num >> k; 30 for(int i = 0
; i < num.length(); i++) { 31 if(num[i] == '0' || num[i] == '5') { 32 ans += power(2, i); 33 ans %= MODE; 34 } 35 } 36 cur += power(power(2, num.length()) - 1, MODE - 2) * (power(2, num.length() * k) - 1); 37 cur %= MODE; 38 ans *= cur; 39 ans %= MODE; 40 41 cout << ans; 42 }