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;
}
posted @ 2025-10-04 08:25  panxz2009  阅读(100)  评论(0)    收藏  举报