# 111學年度下學期進階班期末考題解
太簡單我就不給`code`了
好累喔
## a896: 五星好平
簡述:
$arr[N]$切成$K$段
每段總和要一樣
切法有幾種?
### #0 遍歷 $O(N)$
直接判每個數字是否相等,是就$1$,反之$0$
### #1 遍歷 $O(N)$
直接$O(N)$跑過去,維護兩個區間的值,查看相等的次數
### #2 greedy $O(N)$
先記一數$sum$為陣列所有值之總和
如果$sum$不整除$K$,則為$0$
不然$O(N)$跑過去維護區間總和,如果到$\frac{sum}{K}$重新記錄維新的區間
如果可以找到$K$個區間並且所有區間的總和都是$\frac{sum}{K}$,就$1$,反之$0$
### #3 math $O(N)$
答案就是$C^N_K-C^{N-1}_K=C^{N-1}_{K-1}$
然後因為有除法,所以要用模逆元
```cpp=
LL a, b, c;
a = b = c = 1;
for(LL i = 1; i < N; i ++ )
a = (a * i) % mod;
for(LL i = 1; i < K; i ++ )
b = (b * i) % mod;
for(LL i = 1; i < N - K; i ++ )
c = (c * i) % mod;
cout << a * inv(b) % mod * inv(c) % mod << endl;
```
### #4 greedy+math $O(N)$
就跟#2一樣
只是如果在切區間的邊界剛好就是一群的$0$的話就要去記錄起來
因為切的那一刀可以在任意一個$0$之間
舉例來說:
$\{1,\ 0,\ 0,\ 1,\ 0,\ 1\},\ K=3$
要把兩個$0$跟一個$0$記錄起來
然後答案就會是`(2+1)*(1+1)=6`
然後用#2的方法的話要特判只有$0$出現的時候
不然會吃WA
```cpp=
LL sum = 0;
for(auto &i : arr)
sum += i;
if(sum == 0)
return /*#3的答案*/
if(sum % K)
return 0;
sum /= K;
LL cnt = 0, num = 0, ans = 1;
for(LL i = 0; i < N; i ++ ) {
num += arr[i];
if(num == sum) {
LL tmp = 0;
i ++ ;
while(i < N && arr[i] == 0)
tmp ++ ;
ans *= tmp + 1;
num = 0;
cnt ++ ;
}
}
cout << (cnt == K ? ans : 0) << endl;
```
### #5 Brute-force $O(C^{N-1}_{K-1})$
直接暴搜每個區間切開的地方
然後區間和一個一個加
最後判是否都相等
```cpp=
#define pb emplace_back
#define ppb pop_back
LL N, K, ans = 0, arr[30];
vector<LL> vec = {0};
void BF(LL p = 1) {
if(vec.size() == K) {
vector<LL> tmp;
for(LL i = 0; i < K; i ++ ) {
LL num = 0;
LL r = (i == K - 1 ? N : vec[i + 1]);
for(LL j = vec[i]; j < r; j ++ )
num += arr[j];
tmp.pb(num);
}
LL num = tmp[0];
for(auto &i : tmp)
if(i != num)
return;
ans ++ ;
return;
}
for(LL i = p; i < N; i ++ ) {
vec.pb(i);
BF(i + 1);
vec.ppb();
}
}
```
### #6 滾動DP + map $O(KN)$
用`map`陣列去維護`DP`
`mp[k][cur]=總和為`cur時,分成`k`份時的方法數
每當輸入一個$a_i$就更新總和`cur`
並另`j = k ~ 2`去看目前的`cur`是否整除`j`
如果是,就轉移`mp[j][cur] += mp[j - 1][cur / j * (j - 1)]`
因為`j = 1`的時候`cur / j * (j - 1)`就會是`0`,必須單獨拉出來`++`
如果不單獨操作就會爛掉(範測第二個)
```cpp=
#include<bits/stdc++.h>
#define IO cin.tie(0) -> sync_with_stdio(0)
#define endl "\n"
using namespace std;
using LL = long long;
const LL mod = 1e9 + 7;
int main() {
IO;
LL T;
cin >> T;
while(T -- ) {
LL n, k, cur = 0, prev = 0, num;
cin >> n >> k;
map<LL, LL> mp[k+1];
for(LL i = 0; i < n; i ++ ) {
cin >> num;
cur += num;
prev = mp[k][cur];
/***** 轉移 *****/
for(LL j = k; j > 1; j -- )
if(cur % j == 0)
mp[j][cur] = (mp[j][cur] + mp[j-1][cur / j * (j - 1)]) % mod;
/***************/
mp[1][cur] ++ ;
mp[1][cur] %= mod;
}
cout << (mp[k][cur] - prev + mod) % mod << endl;
}
}
```
---
## a901: JoGuessr
函數是一個碗型,可以先用`y=0`對維度`x`三分搜,搜到最小值
再用`x=三分搜最小值`對維度`y`做三分搜
就結束了
最多只要做`16`次左右
好像就沒有什麼好講的了
---
## a919: 最終等級水流消毒劑
${FDCS(n) = \left\{ \begin{array}{l} 1 \qquad \qquad n=1 \\ \Sigma_{k=1}^{n-1}\left[\left(\Sigma_{i=1}^{k}i^{n+k-i}\right)*FDCS(k)\right] \qquad \qquad else \\ \end{array} \right.}$
給定$n$,求$FDCS(n)$
其實這題是拿來送分的:thinking_face:
### #0 手動打表 $O(1)$
就從$1$列到$7$
沒什麼好講的
### #1 遞迴 $O(T*窩不會算反正很大)$
直接套上面的遞迴式
沒什麼好講的
### #2 DP+快速冪 $O(T*N^3)$
直接套上面的遞迴式來做$DP$
因為有大數字次方,所以要用快速冪
```cpp=
LL pwr(LL a, LL b, LL r = 1) {
for(; b; a = a * a % mod, b >>= 1)
if(b & 1)
r = r * a % mod;
return r;
}
```
```cpp=
dp[1] = 1;
for(LL n = 2; n < maxN; n ++ ) {
dp[n] = 0;
for(LL k = 1; k <= n - 1; k ++ ) {
LL num = 0;
for(LL i = 1; i <= k; i ++ ) {
num = (num + pwr(i, n + k - i)) % mod;
}
dp[n] = (dp[n] + num * dp[k]) % mod;
}
}
for(LL i = 0; i < maxN; i ++ ) {
if(i % 10 == 0)
cout << endl;
cout << dp[i] << ", ";
}
```
### #3 DP+快速冪 建表 $O(N^3)$
#2+建表
把$T$壓掉
### #4 本地打表 $O(T)$
因為我時限壓$0.1s$,所以一般$DP$不太可能過(除非用毒瘤$IO$優化)
所以要直接在本機先建好表格,直接宣告進陣列,最後直接$O(T)$
這樣的話`dp[]`大概長這樣
```cpp=
LL dp[maxN] = {
0, 1, 1, 10, 1158, 2182470, 305056381, 702082639, 752288299, 477389216,
31433074, 336058181, 593011675, 356559883, 515228734, 815882365, 516395221, 259603426, 275583033, 563699379,
273172876, 803594869, 376459799, 353678446, 586795639, 88101652, 557301679, 207730881, 48371837, 282212452,
7081319, 536987975, 935203404, 266370975, 827004699, 267505718, 174160064, 634356490, 333956301, 511844379,
885388304, 8072856, 136536264, 155852079, 667718194, 811157733, 153136736, 124950019, 574698766, 100319347,
477442139, 634791222, 337075155, 662862920, 726202620, 26903232, 516354729, 881830305, 837006395, 252454848,
254130316, 795729438, 915357505, 761287326, 155107684, 898600656, 619439611, 666466076, 171507634, 611394335,
351657043, 975475572, 716410806, 761030125, 663081781, 162182692, 61447863, 341570784, 675757091, 642697685,
356765037, 227375166, 157736770, 595898735, 608726393, 755658579, 275875603, 78344815, 84461062, 471213261,
972558343, 823928395, 277298156, 488523380, 559463723, 218520738, 980656872, 577939757, 896131049, 147250089,
481006235, 61276048, 824877846, 812981205, 745109522, 174517502, 379894848, 879889549, 685348645, 104539313,
700794798, 12189210, 663846524, 237862331, 865980705, 815936315, 787049217, 266207480, 724294525, 11849353,
756361719, 650254096, 575328055, 383594245, 7484244, 935444700, 282083903, 185725873, 309135729, 799895081,
790130249, 580254395, 254281866, 452919717, 704571890, 928054673, 922186589, 794750560, 585165264, 227130235,
729763789, 802464579, 458137939, 893743199, 81346751, 189344264, 489276569, 45908973, 760498563, 534608392,
526044102, 930290407, 700449761, 505382214, 964680818, 107651495, 62189544, 248248515, 442224332, 401476474,
794880138, 80124355, 644203663, 157393343, 259417538, 46003290, 759758656, 8825068, 31319805, 80114112,
651032734, 831232606, 169192627, 952636179, 539608933, 660187854, 588897357, 311368973, 468315640, 962097104,
753379453, 361652529, 366320888, 452377551, 591283833, 607748576, 335227937, 237841392, 637805222, 154093331,
432773831, 512317024, 419544035, 927480250, 223715398, 616313944, 557918787, 265417324, 296332362, 555793430,
310874129, 94881716, 486139843, 754686377, 489685195, 569580815, 766488173, 811270212, 590056031, 83740899,
201861289, 918415532, 39776803, 755667976, 762858856, 493131157, 293727639, 419363579, 614753101, 490540101,
984408602, 589279324, 895767194, 755172025, 6205969, 375348199, 533768154, 81592791, 928765001, 702345552,
982979241, 459499478, 763042757, 126686003, 552985958, 482750359, 818718622, 748484428, 708268589, 648794433,
473905699, 647582466, 770158948, 397157026, 961471182, 358826159, 297046870, 699642581, 888948000, 440683007,
521062778, 130770701, 520223939, 211521658, 899648525, 833235135, 636577900, 179224151, 339483581, 955269534,
706092177, 24748204, 965866179, 311613056, 833814194, 176369778, 370197753, 103011921, 645941381, 823109475,
244702026, 446083030, 883734438, 363945461, 255830208, 628672405, 193846527, 111325803, 689914060, 398875936,
625238181, 522966817, 5906822, 561284876, 941250331, 788336779, 820701656, 833734278, 852037710, 576683781,
36551254, 82490363, 776643660, 823767907, 522479617, 470805974, 801058154, 429059615, 317287290, 28373308,
156669444, 369535646, 820005077, 966349005, 17425595, 601871796, 344822813, 450093249, 43011813, 182753917,
365808458, 173287449, 975748074, 896467879, 816982178, 140824878, 956121017, 146854490, 991656048, 279369914,
600027588, 190213014, 477766519, 995297939, 192626396, 622852686, 348388433, 837517092, 994516811, 539845621,
306653137, 215901575, 74092752, 85378281, 259149972, 141941182, 478024722, 244259025, 972194731, 721420118,
304432708, 534777820, 710566197, 700216698, 781660848, 499316348, 902395596, 551269912, 122829563, 899620761,
42408607, 130778020, 267328015, 537603777, 720559481, 772174292, 740079703, 419418968, 149102240, 950468464,
941507049, 960705655, 328042283, 107953050, 412460424, 942509934, 744657612, 884367732, 818170107, 508992613,
174295590, 258435637, 800618410, 439541821, 210632622, 318599551, 257366743, 112254316, 593205846, 337414888,
821861221, 59215144, 928196581, 796439573, 386885760, 644540454, 620416951, 885640438, 176695075, 575842112,
430679625, 683424291, 964059908, 535495714, 346521303, 66145163, 321162832, 26966819, 80257910, 352567893,
606762953, 326757128, 936438254, 493689268, 330177705, 548497940, 103064084, 987717118, 409889108, 476642393,
300076332, 990026161, 957603752, 279575203, 796141463, 430237782, 388412904, 914557304, 66398603, 419108079,
564739483, 360277144, 833370810, 793163343, 77555321, 459720549, 331852100, 870458104, 980273490, 406844238,
782707113, 625438948, 625279668, 481259993, 680191665, 390376751, 817287968, 329858310, 282230752, 250907860,
374236023, 313034982, 463415697, 622907436, 666586592, 451750478, 730276932, 371013370, 456813292, 904847358,
833818010, 332155020, 529792504, 311749609, 91093636, 793001596, 112262142, 950155165, 442268563, 586364148,
890744722, 378745118, 417531072, 348309723, 905741085, 674560685, 842495816, 478699582, 273295856, 623924882,
651503183, 260801639, 929792563, 570120042, 827395507, 377875481, 409778880, 254865961, 377370235, 603629622,
489235240, 708757527, 631945509, 106393814, 655044539, 540523391, 24746001, 448628979, 30453128, 917523298,
654354517, 835283546, 420232474, 781568290, 679088875, 310939466, 13418200, 175669958, 352628310, 159439479,
322651599, 973805882, 528339253, 360787657, 375391661, 171647216, 757806674, 557536089, 382163354, 831564544,
993118007, 590429555, 513990657, 238959287, 235625864, 726064841, 740374275, 910521402, 6011372, 796798874,
640854564, 362691708, 28269056, 552405639, 827754295, 324883111, 253656191, 411745874, 916352411, 821617329,
325454308, 806095418, 879753666, 86822057, 803226698, 817325532, 435364603, 605335068, 672227740, 941122665,
740201925, 692424682, 787635121, 575980237, 122392875, 768836805, 525855163, 692297897, 416003183, 709392402,
709206520, 369460428, 580925065, 901822521, 160582874, 903953869, 816717404, 515847646, 201117415, 362018594,
278191305, 910516143, 321783859, 554552090, 287020070, 944479569, 455267282, 665381735, 206313038, 3064210,
325776338, 522599769, 928844280, 273628329, 962068420, 653471535, 794286560, 157512688, 495719215, 448511035,
798686887, 581226982, 267792698, 50620045, 926275063, 673258316, 85790002, 69455051, 92792365, 260690128,
566944151, 376676829, 262517915, 97006512, 216334503, 122558827, 815783758, 7491383, 435669107, 594402063,
585335080, 200308901, 254307867, 623408278, 101584531, 638749265, 213822733, 574927059, 353380567, 908062966,
438001563, 956535097, 557189227, 168323628, 946320051, 600228771, 843452872, 394931229, 294479675, 679259740,
726660354, 789873018, 236408406, 46354911, 359477590, 764921787, 31421023, 832683365, 377639624, 266070748,
150097868, 702863446, 881824289, 761307806, 523963062, 316969153, 156637945, 478522591, 129518749, 637186672,
183004245, 434886008, 134834657, 726075096, 541779283, 417184133, 991486034, 333450250, 19049240, 655388726,
884136736, 623418196, 522422556, 510611863, 765373671, 484538332, 885044951, 677315717, 775337123, 665612125,
804493962, 223379614, 698348588, 369372909, 97424508, 80722496, 169028626, 503967942, 873647467, 742269751,
778760444, 233358696, 140037546, 489553189, 261780957, 614723289, 339198539, 143515523, 69141904, 454438360,
464165491, 757396683, 45354236, 520691312, 861326712, 816641656, 978083627, 313056924, 566092411, 754476393,
909750501, 470321615, 900387754, 588995960, 84350539, 209459107, 624527679, 671610616, 607393265, 297698676,
137623511, 419287093, 287724738, 959399556, 581333666, 754316716, 429822404, 549169627, 478442864, 367972293,
496002356, 948521882, 921015644, 582549666, 645172896, 175915527, 639517871, 260430783, 929534990, 793092840,
579793527, 312300806, 369657329, 712828952, 223143249, 245302915, 450372967, 437253970, 714824008, 571989253,
891339454, 542008010, 653542156, 918658026, 275425895, 565117033, 414620805, 553138750, 277789800, 770594228,
195125948, 624115475, 883251205, 34848122, 173720013, 936840881, 721277277, 38503524, 38164678, 563954134,
283484617, 719504594, 778921963, 445190187, 389795454
};
```
---
## a937: 嗟!
### #0 爆開算 $O(1)$
直接把階乘算出來,算$0$的個數
### #1 影片中的演算法 $O(log_5n)$
有認真點進去影片的,就知道裡面就有解法了
用$LL$存然後一直除$5$再加到$ans$
最後輸出$ans$即可
### #2 string 大數 $O(log_5n*n)$
跟 #1 一樣只是用`string`大數
除法就用長除法的方式去做
不然也可以`*2/10`,`/10`就直接去掉後面一位就可以了
### #3 LL array 大數 $O(log_5n*n)$
跟 #2 一樣只是用`LL array`存大數
一格存`19`位的數字
除法就用多項式除法的方式去做,或一樣`*2/10`
```cpp=
#include<bits/stdc++.h>
#define IO cin.tie(0) -> sync_with_stdio(0)
#define endl "\n"
#define F first
#define S second
#define pLL pair<LL, LL>
#define pb emplace_back
#define pf emplace_front
#define ppb pop_back
#define ppf pop_front
#define LL lolita
#define lolita long long
using namespace std;
void init();
const LL mod = 1e9 + 7, inf = numeric_limits<LL>::max(), maxN = 1e18;
LL arr[100];
bool check() {
for(auto &i : arr) {
if(i)
return 1;
}
return 0;
}
void db5() {
LL pass = 0;
for(auto &i : arr) {
i = i * 2 + pass, pass = 0;
if(i / maxN)
i -= maxN, pass = 1;
}
arr[0] /= 10;
for(LL i = 1; i < 60; i ++ ) {
arr[i - 1] += maxN / 10 * (arr[i] % 10);
arr[i] /= 10;
}
}
void solve() {
string str;
cin >> str;
LL len = str.length();
for(LL i = 0; ; i ++ ) {
bool bln = 0;
LL p = len - 18 * (i+1), k = 18;
if(p < 0)
k += p, p = 0, bln = 1;
string tmp = str.substr(p, k);
arr[i] = atoll(tmp.c_str());
if(bln)
break;
}
LL ans[100];
memset(ans, 0, sizeof(ans));
while(check()) {
db5();
LL pass = 0;
for(LL i = 0; i < 100; i ++ ) {
ans[i] += arr[i] + pass, pass = 0;
if(ans[i] / maxN)
ans[i] -= maxN, pass = 1;
}
}
bool bln = 1;
for(LL i = 99; i >= 0; i -- ) {
string tmp = to_string(ans[i]);
if(!bln) {
while(tmp.length() != 18)
tmp = '0' + tmp;
}
if(ans[i])
bln = 0;
if(bln && ans[i] == 0)
continue;
cout << tmp;
}
if(bln)
cout << 0;
cout << endl;
}
int main() {
// IO;
LL T;
cin >> T;
while(T -- )
solve();
}
void init() {
}
```