打卡信奥刷题(3246)用C++实现信奥题 P8565 Sultan Rage
P8565 Sultan Rage
题目描述
有一个数列 {an}\{a_n\}{an} 满足对 n>mn > mn>m 均有 an=∑j=1man−ja_n=\sum\limits_{j=1}^m a_{n-j}an=j=1∑man−j,并且 a1,a2,⋯ ,ama_1,a_2,\cdots,a_ma1,a2,⋯,am 是输入中给出的正整数。
qqq 次询问,每一次给出一个正整数 xxx,问有多少个不可重正整数集 SSS 满足 ∑s∈Sas=x\sum\limits_{s\in S}a_s=xs∈S∑as=x。答案对质数 998244353998244353998244353 取模。
本题有多组数据。
输入格式
本题有多组数据。
第一行一个整数 TTT 表示数据组数。对于每一组数据:
第一行两个整数 m,qm,qm,q。
第二行 mmm 个整数 a1,a2,⋯ ,ama_1,a_2,\cdots,a_ma1,a2,⋯,am。
第三行 qqq 个整数,每一个整数代表一次询问。
输出格式
对于每组询问输出一行表示答案。
输入输出样例 #1
输入 #1
2
2 5
1 1
3 5 7 9 11
3 5
1 2 5
4 7 10 18 22
输出 #1
3
3
3
5
5
0
1
1
1
1
说明/提示
对于所有数据,T=5T=5T=5,2≤m≤1002 \le m \le 1002≤m≤100,1≤q,ai≤1001 \le q,a_i \le 1001≤q,ai≤100,1≤x≤10181 \le x \le 10^{18}1≤x≤1018。
测试点编号m≤q≤ai≤x≤特殊性质1∼28881003∼51515103617∼111A12∼16217∼20 \def\arraystretch{1.5} \begin{array}{c|c|c|c|c|c}\hline \textbf{测试点编号}&\bm{m\le}&\bm{q \le }&\bm{a_i \le }& \bm{x \le}&\bm{\textbf{特殊性质}}\cr\hline \textsf1\sim \sf2 & 8&8 & 8 & 100\cr\hline \sf3\sim 5 & 15& &15&10^3 \cr\hline \textsf6 & & & & 1 &\cr\hline \sf7\sim 11 & & 1& & & \textsf{A}\cr\hline \sf12\sim 16 & 2& & &\cr\hline \sf17\sim 20 & &\cr\hline \end{array} 测试点编号1∼23∼567∼1112∼1617∼20m≤8152q≤81ai≤815x≤1001031特殊性质A
A\textsf AA:m=10m=10m=10,且 xxx 在所有可能的 xxx 中随机生成。
C++实现
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
ll read() {
ll ret = 0, sgn = 0;
char ch = getchar();
while (!isdigit(ch)) sgn |= ch == '-', ch = getchar();
while (isdigit(ch)) ret = ret * 10 + ch - '0', ch = getchar();
return sgn ? -ret : ret;
}
const int N = 180, mod = 998244353;
const ll INF = 1e18;
int n, q;
ll a[N], sum[N];
map<ll, int> mp[N];
int dfs(ll x, int cur) {
if (x < 0 || x > sum[cur]) return 0;
if (!cur) return (x == 0);
if (mp[cur].count(x)) return mp[cur][x];
return mp[cur][x] = (dfs(x - a[cur], cur - 1) + dfs(x, cur - 1)) % mod;
}
int main() {
int T = read();
while (T--) {
n = read(), q = read();
for (int i = 1; i <= n; i++) a[i] = read();
int m = n;
while (a[m] <= INF) {
a[++m] = 0;
for (int i = 1; i <= n; i++) a[m] += a[m - i];
}
n = m - 1;
for (int i = 1; i <= n; i++) {
sum[i] = sum[i - 1] + a[i];
mp[i].clear();
}
while (q--) {
ll x = read();
printf("%d\n", dfs(x, n));
}
}
return 0;
}

后续
接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容
更多推荐

所有评论(0)