QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#634158 | #9457. Prime Set | ucup-team037# | TL | 729ms | 22548kb | C++20 | 6.2kb | 2024-10-12 16:47:17 | 2024-10-13 19:27:48 |
Judging History
answer
// Hallelujah, praise the one who set me free
// Hallelujah, death has lost its grip on me
// You have broken every chain, There's salvation in your name
// Jesus Christ, my living hope
#include <bits/stdc++.h>
using namespace std;
#define REP(i, s, e) for (int i = (s); i < (e); i++)
#define RREP(i, s, e) for (int i = (s); i >= (e); i--)
template <class T>
inline bool mnto(T& a, T b) {return b < a ? a = b, 1 : 0;}
template <class T>
inline bool mxto(T& a, T b) {return a < b ? a = b, 1: 0;}
typedef unsigned long long ull;
typedef long long ll;
typedef long double ld;
#define FI first
#define SE second
typedef pair<int, int> ii;
typedef pair<ll, ll> pll;
typedef tuple<int, int, int> iii;
#define ALL(_a) _a.begin(), _a.end()
#define SZ(_a) (int) _a.size()
#define pb push_back
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<ii> vii;
typedef vector<iii> viii;
#ifndef DEBUG
#define cerr if (0) cerr
#endif
const int INF = 1000000005;
const ll LINF = 1000000000000000005ll;
const int MAXN = 3005;
const int MAXA = 2000005;
template <class T = int, int PW = 0>
struct FlowGraph {
struct edge {
int v;
T cap, flow;
int rid;
};
int n;
T lim;
T inf;
vector<vector<edge>> adj;
vector<int> dist, ptr;
FlowGraph(): n(0), inf(0) {}
FlowGraph(int n): n(n), inf(0) {
dist.resize(n, -1);
ptr.resize(n, 0);
adj.resize(n);
}
void add_edge(int u, int v, T cap = 1, T rcap = 0) {
int id = adj[u].size(), rid = adj[v].size();
adj[u].push_back((edge) {v, cap, 0, rid});
adj[v].push_back((edge) {u, rcap, 0, id});
inf = max(inf, max(cap, rcap) + 5);
}
bool bfs(int src, int sink) {
for (int i = 0; i < n; i++) {
dist[i] = -1;
}
queue<int> q;
dist[src] = 0;
q.push(src);
while (!q.empty()) {
int u = q.front(); q.pop();
for (edge e : adj[u]) {
if (e.cap - e.flow < lim) continue;
if (dist[e.v] != -1) continue;
dist[e.v] = dist[u] + 1;
q.push(e.v);
}
}
return dist[sink] != -1;
}
T dfs(int u, int sink, T flow) {
if (u == sink) return flow;
for (; ptr[u] < adj[u].size(); ptr[u]++) {
edge &e = adj[u][ptr[u]];
if (dist[u] + 1 != dist[e.v]) continue;
if (e.cap - e.flow < lim) continue;
T cflow = min(flow, e.cap - e.flow);
cflow = dfs(e.v, sink, cflow);
if (cflow) {
e.flow += cflow;
adj[e.v][e.rid].flow -= cflow;
return cflow;
}
}
return 0;
}
T flow(int src, int sink) {
T res = 0;
for (lim = ((T) 1 << PW); lim > 0; lim >>= 1) {
while (bfs(src, sink)) {
for (int i = 0; i < n; i++) {
ptr[i] = 0;
}
while (T cflow = dfs(src, sink, inf)) {
res += cflow;
}
}
}
return res;
}
bool leftCut(int x) {
return dist[x] != -1;
}
};
bool isp[MAXA];
int t;
int n, k;
int a[MAXN];
bool avail[MAXN];
int main() {
#ifndef DEBUG
ios::sync_with_stdio(0), cin.tie(0);
#endif
REP (i, 2, MAXA) {
isp[i] = 1;
}
for (int i = 2; i * i < MAXA; i++) {
if (!isp[i]) {
continue;
}
for (int j = i * i; j < MAXA; j += i) {
isp[j] = 0;
}
}
cin >> t;
while (t--) {
cin >> n >> k;
FlowGraph fg(n + 2);
int src = n, sink = n + 1;
int ans = 0, ocnt = 0;
vi vone;
REP (i, 0, n) {
cin >> a[i];
if (a[i] == 1) {
ocnt++;
vone.pb(i);
}
}
REP (i, 0, n) {
avail[i] = 0;
REP (j, 0, n) {
if (i == j) {
continue;
}
avail[i] |= isp[a[i] + a[j]];
}
}
REP (i, 0, n) {
if (a[i] == 1) {
a[i] = 0;
}
}
REP (i, 0, n) {
if (a[i] == 0) {
continue;
}
if (a[i] % 2 == 0) {
fg.add_edge(i, sink);
} else {
fg.add_edge(src, i);
}
}
REP (i, 0, n) {
if (a[i] == 0) {
continue;
}
REP (j, 0, n) {
if (a[j] == 0) {
continue;
}
if (a[j] % 2 == 1) {
continue;
}
if (isp[a[i] + a[j]]) {
fg.add_edge(i, j);
}
}
}
int flow = fg.flow(src, sink);
//cerr << flow << '\n';
int mn = min(flow, k);
k -= mn;
int base = mn * 2;
REP (ones, 0, ocnt + 1) {
int extra = 0;
REP (i, 0, n) {
if (a[i] == 0) {
continue;
}
bool filled = fg.adj[i][0].flow != 0;
//cerr << ' ' << i << ' ' << filled << '\n';
if (filled) {
continue;
}
if (avail[i]) {
extra++;
}
}
int res = base;
int tk = k;
int mn = min(tk, (ocnt - ones) / 2);
tk -= mn;
res += mn * 2;
res += min(tk, extra);
mxto(ans, res);
if (ones == ocnt) {
break;
}
int i = vone.back(); vone.pop_back();
a[i] = 1;
fg.add_edge(src, i);
REP (j, 0, n) {
if (a[j] % 2 == 1) {
continue;
}
if (isp[a[i] + a[j]]) {
fg.add_edge(i, j);
}
}
int flow = fg.flow(src, sink);
//cerr << flow << '\n';
mn = min(flow, k);
k -= mn;
base += mn * 2;
}
cout << ans << '\n';
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 6ms
memory: 5588kb
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: 729ms
memory: 22548kb
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: -3
Extra Test Failed : Time Limit Exceeded on 4
input:
2 3000 3000 1 2 1 1 2 2 1 1 1 2 1 2 2 1 1 1 2 1 1 1 1 2 2 2 1 1 1 2 2 1 1 2 2 2 2 1 1 1 1 1 1 1 2 2 1 1 1 2 2 1 2 1 2 2 2 1 1 2 2 2 2 1 2 2 2 2 2 1 2 2 1 1 1 2 2 1 1 1 2 1 2 2 2 2 2 1 2 2 1 1 1 2 2 2 2 2 2 1 1 2 2 2 2 1 2 1 2 2 1 2 1 1 1 2 2 2 1 2 2 1 1 2 1 2 2 1 2 1 2 2 2 2 1 2 1 1 1 1 1 2 1 2 1 1 ...