题目大意

题意

分析

按位考虑 aia_i

考虑 dp[i][j]dp[i][j] 表示为考虑到第 ii 位总和为 jj 的方案数

为满足要求

image-20220828165425208

会发现对于第 ii 位来说 11 的个数都是连续的,我们可以枚举第 ii 位有 kk11

image-20220828165700675

那么转移方程为

高位到低位考虑

1
2
3
4
5
6
7
8
9
f[cnt+1][0] = 1;
for(int i = cnt+1;i > 0;i--){
for(int j = 0;j <= n;j++){
for(int o = 0;o <= k;o++){
if(j + o*(1LL<<(i-1)) > n) break;
f[i-1][j+((1LL<<(i-1)))*o] = (f[i-1][j+((1LL<<(i-1)))*o] + f[i][j])%mod;
}
}
}

时间复杂度O(n2logn)O(n^{2} log^n)

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
int n,k;
int f[32][10005];
signed main()
{
cin >> k >> n;
int cnt = 0;
int t = n;
while(t){
cnt++;
t >>= 1;
}
cnt--;
f[cnt+1][0] = 1;
for(int i = cnt+1;i > 0;i--){
for(int j = 0;j <= n;j++){
for(int o = 0;o <= k;o++){
if(j + o*(1LL<<(i-1)) > n) break;
f[i-1][j+((1LL<<(i-1)))*o] = (f[i-1][j+((1LL<<(i-1)))*o] + f[i][j])%mod;
}
}
}

cout << f[0][n] << endl;
return 0;
}