2025 百度之星第二场 Yummy 题解
题目
记 \(sum_i=\sum_{i=1}^ns_i\cdot v_i\cdot k^i\)。
结论 1:\(|sum_i|< 2\cdot k^{i+1}\)。证明考虑极端情况: \(v_1=v_2=...=v_{i-1}=k,s_1=s_2=...=s_{i-1}=1\),那么 \(|sum_i|=k^2+k^3+...+k^i+k^{i+1}<2\cdot k^{i+1}\)。
结论 2:\(sum_i\) 一定是 \(k^{i+1}\) 的倍数。证明可以考虑数学归纳法。当 \(i=n-1\) 时由 \(sum_n=0\) 显然成立。对于 \(i<n-1\),\(k^{i+2}|sum_{i+1}=sum_{i}+s_{i+1}\cdot v_{i+1}\cdot k^{i+1}\),即 \(k^{i+2}-s_{i+1}\cdot v_{i+1}\cdot k^{i+1}=k^{i+1}\cdot(k-s_{i+1}\cdot v_{i+1})|sum_i\)。
推论:\(sum_i\) 一定可以被表示成为 \(c\cdot k^{i+1}\),其中 \(c\in\{-1,0,1\}\)。
故可以 dp。考虑设 \(f_{i,c}\) 表示 \(sum_i=c\cdot k^{i+1}\) 的方案数,其中 \(c\in\{-1,0,1\}\)。转移讨论 \(s_i\) 的正负值:
若 \(s_i=1\),则有
\[\begin{aligned}
f_{i,0}=f_{i-1,0}+f_{i-1,-1}\\
f_{i,1}=f_{i-1,0}+f_{i-1,1}\\
f_{i,-1}=0
\end{aligned}
\]
若 \(s_i=-1\),则有
\[\begin{aligned}
f_{i,0}=f_{i-1,0}+f_{i-1,1}\\
f_{i,-1}=f_{i-1,0}+f_{i-1,-1}\\
f_{i,1}=0
\end{aligned}
\]
答案为 \(f_{n,0}\)。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e5 + 10, md = 998244353;
int n, k, s[maxn], f[maxn][3];
void solve() {
cin >> n >> k;
for(int i = 1; i <= n; i++) cin >> s[i];
f[0][0] = 1, f[0][1] = f[0][2] = 0;
for(int i = 1; i <= n; i++) {
if(s[i] == 1) {
f[i][0] = (f[i - 1][0] + f[i - 1][2]) % md;
f[i][1] = (f[i - 1][0] + f[i - 1][1]) % md;
f[i][2] = 0;
}
else {
f[i][0] = (f[i - 1][0] + f[i - 1][1]) % md;
f[i][2] = (f[i - 1][0] + f[i - 1][2]) % md;
f[i][1] = 0;
}
}
cout << f[n][0] << "\n";
}
signed main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int T; cin >> T;
while(T--) solve();
return 0;
}

浙公网安备 33010602011771号