题目描述
有 $T$ 次询问,每次询问使用小于等于 $m$ 的素数相加得到 $n$ 的方案数,其中方案数对 $2$ 取模
$T,n,m\le 3\times 10^5$
Solution
能够想到用 $bitset$ 优化 $01$ 背包
注意到可以将询问离线下来降低空间复杂度
时间复杂度 $O(\frac{nm}{64\log m})$
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| #include <iostream> #include <cstdio> #include <bitset> #include <algorithm> #define maxn 300010 #define cQ const Query using namespace std;
int n, m;
bitset<maxn> f;
int pri[maxn], c1; bool isp[maxn]; void init_isp(int n) { for (int i = 2; i <= n; ++i) { if (!isp[i]) pri[++c1] = i; for (int j = 1; i * pri[j] <= n && j <= c1; ++j) { isp[i * pri[j]] = 1; if (i % pri[j] == 0) break; } } }
struct Query { int x, y, id;
friend bool operator < (cQ &u, cQ &v) { return u.y < v.y; } } Q[maxn]; int ans[maxn];
int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
int T; cin >> T; init_isp(300000); for (int i = 1; i <= T; ++i) cin >> Q[i].x >> Q[i].y, Q[i].id = i; sort(Q + 1, Q + T + 1); f[0] = 1; for (int i = 1, j = 0; i <= T; ++i) { while (j < c1 && pri[j + 1] <= Q[i].y) f ^= f << pri[++j]; ans[Q[i].id] = f[Q[i].x]; } for (int i = 1; i <= T; ++i) cout << ans[i] << "\n"; return 0; }
|