QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#638564 | #9457. Prime Set | hos_lyric | AC ✓ | 49ms | 6248kb | C++14 | 4.8kb | 2024-10-13 16:14:29 | 2024-10-13 16:14:32 |
Judging History
answer
#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
using Int = long long;
template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; };
template <class T> ostream &operator<<(ostream &os, const vector<T> &as) { const int sz = as.size(); os << "["; for (int i = 0; i < sz; ++i) { if (i >= 256) { os << ", ..."; break; } if (i > 0) { os << ", "; } os << as[i]; } return os << "]"; }
template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; }
template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; }
template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; }
#define COLOR(s) ("\x1b[" s "m")
namespace bm {
constexpr int LIM_N0 = 3010;
constexpr int LIM_N1 = 3010;
int n0, n1;
bitset<LIM_N0> yet0, layers0[LIM_N0 + 1];
bitset<LIM_N1> yet1, layers1[LIM_N0], adj[LIM_N0];
int to[LIM_N0], fr[LIM_N1], tof;
int used[LIM_N0], lev[LIM_N0];
void init(int n0_, int n1_) {
n0 = n0_; n1 = n1_;
for (int u = 0; u < n0; ++u) adj[u].reset();
}
void ae(int u, int v) {
adj[u].set(v);
}
int augment(int u) {
used[u] = tof;
const auto sub = adj[u] & layers1[lev[u]];
for (int v = sub._Find_first(); v < n1; v = sub._Find_next(v)) {
const int w = fr[v];
if (!~w || (used[w] != tof && lev[u] < lev[w] && augment(w))) {
to[u] = v; fr[v] = u; return 1;
}
}
return 0;
}
int run() {
memset(to, ~0, n0 * sizeof(int));
memset(fr, ~0, n1 * sizeof(int));
memset(used, ~0, n0 * sizeof(int));
for (tof = 0; ; ) {
yet0.set();
yet1.set();
layers0[0].reset();
for (int u = 0; u < n0; ++u) if (!~to[u]) layers0[0].set(u);
yet0 ^= layers0[0];
for (int d = 0; layers0[d].any(); ++d) {
layers1[d].reset();
for (int u = layers0[d]._Find_first(); u < n0; u = layers0[d]._Find_next(u)) {
lev[u] = d;
layers1[d] |= adj[u];
}
layers1[d] &= yet1; yet1 ^= layers1[d];
layers0[d + 1].reset();
for (int v = layers1[d]._Find_first(); v < n1; v = layers1[d]._Find_next(v)) {
if (~fr[v]) layers0[d + 1].set(fr[v]);
}
layers0[d + 1] &= yet0; yet0 ^= layers0[d];
}
int f = 0;
for (int u = 0; u < n0; ++u) if (!~to[u]) f += augment(u);
if (!f) return tof;
tof += f;
}
}
// s: true, t: false (s: reachable from unmatched left)
// vertex cover: (0: false, 0: true)
// independent set: (0: true, 1: false)
bool side0[LIM_N0], side1[LIM_N1];
void dfs(int u) {
if (!side0[u]) {
side0[u] = true;
for (int v = adj[u]._Find_first(); v < n1; v = adj[u]._Find_next(v)) {
if (!side1[v]) {
side1[v] = true;
const int w = fr[v];
if (~w) dfs(w);
}
}
}
}
void minCut() {
memset(side0, 0, n0 * sizeof(bool));
memset(side1, 0, n1 * sizeof(bool));
for (int u = 0; u < n0; ++u) if (!~to[u]) dfs(u);
}
} // namespace bm
/*
matching: (1 + 1) or (even + odd = prime)
M: max matching
B: max matching as bipartite
floor(B/2) = M
(>=)
{u,v} -> (u,v),(v,u)
M >= 2B
(<=)
graph on [N]
path: can take >=half of edges
even cycle: can take half of edges
odd cycle: must contain 1, connect all odd cycles at 1, can take floor(len/2)
*/
constexpr int LIM = 2'000'010;
bitset<LIM> isp;
int N, K;
vector<int> A;
int main() {
isp.set();
isp.reset(0);
isp.reset(1);
for (int p = 2; p < LIM; ++p) if (isp[p]) {
for (int n = 2 * p; n < LIM; n += p) isp.reset(n);
}
for (int numCases; ~scanf("%d", &numCases); ) { for (int caseId = 1; caseId <= numCases; ++caseId) {
scanf("%d%d", &N, &K);
A.resize(N);
for (int u = 0; u < N; ++u) {
scanf("%d", &A[u]);
}
int n = 0;
bm::init(N, N);
for (int u = 0; u < N; ++u) {
bool any = false;
for (int v = 0; v < N; ++v) if (isp[A[u] + A[v]]) {
if (u != v) any = true;
bm::ae(u, v);
}
if (any) ++n;
}
const int b = bm::run();
const int m = b / 2;
// cerr<<"n = "<<n<<", b = "<<b<<", m = "<<m<<endl;
int ans = K;
ans += min(K, m);
chmin(ans, n);
printf("%d\n", ans);
}
#ifndef LOCAL
break;
#endif
}
return 0;
}
这程序好像有点Bug,我给组数据试试?
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 9ms
memory: 6248kb
input:
4 4 2 2 3 4 5 5 3 3 4 12 3 6 6 3 1 3 6 8 1 1 1 0 1
output:
4 3 6 0
result:
ok 4 lines
Test #2:
score: 0
Accepted
time: 49ms
memory: 5436kb
input:
110 3 3 2 2 2 3 1 1 1 1 3 2 1 1 1 3 3 1 1 1 4 2 1 1 1 1 10 7 1 1 1 2 4 6 8 10 12 14 18 1 10 5 9 4 10 7 2 4 9 1 6 1 4 9 2 4 9 7 19 5 1 6 1 8 8 1 5 10 9 2 10 2 1 9 6 10 4 3 6 14 4 6 6 8 9 5 3 4 9 2 2 1 10 10 1 15 10 5 4 2 4 10 1 8 4 10 3 10 3 7 10 4 17 5 10 7 2 4 3 1 10 8 2 8 3 4 1 1 1 1 1 20 6 8 4 6 ...
output:
0 2 3 3 4 8 2 10 8 15 10 12 10 10 12 16 10 10 12 16 14 13 13 14 17 0 19 12 12 11 16 10 19 2 12 10 5 14 10 10 13 2 18 2 4 4 11 8 11 8 0 10 10 0 10 0 8 15 12 11 13 18 10 17 9 8 20 19 13 6 4 6 11 9 13 11 6 2 8 12 17 14 6 2 20 2 18 17 6 2 10 0 7 16 2 2 0 2 18 14 11 8 4 6 0 19 890 204 2746 2372
result:
ok 110 lines
Extra Test:
score: 0
Extra Test Passed