[Cometoj#3 C]子序列子序列子序列..._动态规划_数论
子序列子序列子序列...
题目链接:https://cometoj.com/contest/38/problem/C?problem_id=1542
数据范围:略。
题解:
神仙题,感觉这个题比$D$还难一些,$Orz$原题解。
http://static.eduzhixin.com/cometoj/solution/contest_38_1.pdf
代码:
#include <bits/stdc++.h>
#define N 5010
#define M 21
#define Pyd 1000000007
using namespace std;
int a[N];
int dp[M][N];
int tmp[N];
int mod[M];
int n, m;
char *p1, *p2, buf[100000];
#define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++ )
int rd() {
int x = 0, f = 1;
char c = nc();
while (c < 48) {
if (c == '-')
f = -1;
c = nc();
}
while (c > 47) {
x = (((x << 2) + x) << 1) + (c ^ 48), c = nc();
}
return x * f;
}
int main() {
n = rd(), m = rd();
for (int i = 1; i <= n; i ++ ) {
a[i] = rd();
}
int k = 0;
while (m % (1 << k) == 0) k ++ ;
mod[0] = mod[1] = m;
for (int i = 2; i <= k; i ++ ) mod[i] = mod[i - 1] / 2;
dp[0][0] = 1;
for (int i = 1; i <= n; i ++ ) {
for (int j = 0; j < mod[k]; j ++ ) tmp[(j + a[i]) % mod[k]] = dp[k][j];
for (int j = 0; j < mod[k]; j ++ ) {
dp[k][j] += tmp[j];
if (dp[k][j] >= Pyd) dp[k][j] -= Pyd;
}
for (int p = k - 1; p > 0; p -- ) {
for (int j = 0; j < mod[p]; j ++ ) {
int nj = (j + a[i]) % mod[p + 1];
dp[p + 1][nj] += dp[p][j];
if (dp[p + 1][nj] >= Pyd) dp[p + 1][nj] -= Pyd;
}
}
dp[1][a[i]] ++ ;
if (dp[1][a[i]] >= Pyd) dp[1][a[i]] -= Pyd;
}
int ans = 0;
for (int i = 1; i <= k; i ++ ) {
ans += dp[i][0];
if (ans >= Pyd) ans -= Pyd;
}
cout << ans << endl ;
return 0;
}
| 欢迎来原网站坐坐! >原文链接<

浙公网安备 33010602011771号