QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#694170#9457. Prime Setucup-team5217#AC ✓51ms24484kbC++234.5kb2024-10-31 17:24:392024-10-31 17:24:40

Judging History

你现在查看的是最新测评结果

  • [2024-10-31 17:24:40]
  • 评测
  • 测评结果:AC
  • 用时:51ms
  • 内存:24484kb
  • [2024-10-31 17:24:39]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;

const int N = 3030;
const int inf = 0x3f3f3f3f;
const int M = 2e6 + 10;
int head[2 * N], nxt[M], c[M], to[M], e_tot = 1;
int cur[2 * N], dep[2 * N];
int na, nb;
int C[N], a[N], b[N];
int cnta[N], cntb[N];
int visa[N], visb[N];
int S, T;
int pri[500010], vis[2000010], ptot;
int cnt1;

int bfs(int S, int T) {
    for (int i = 0; i <= na + nb + 3; ++i) dep[i] = 0, cur[i] = head[i];
    queue<int> q;
    q.push(S);
    dep[S] = 1;
    while (!q.empty()) {
        int u = q.front();
        q.pop();
        for (int i = head[u]; i; i = nxt[i]) {
            int v = to[i];
            if (c[i] && !dep[v]) {
                dep[v] = dep[u] + 1;
                q.push(v);
            }
        }
    }
    return dep[T];
}

int dfs(int u, int T, int lim) {
    if (u == T || !lim) return lim;
    int flow = 0, k;
    for (int i = cur[u]; i && lim; i = nxt[i]) {
        int v = to[i];
        cur[u] = i;
        if (c[i] && dep[v] == dep[u] + 1) {
            k = dfs(v, T, min(lim, c[i]));
            if (!k) dep[v] = 0;
            c[i] -= k, c[i ^ 1] += k;
            flow += k, lim -= k;
        }
    }
    return flow;
}

int dinic(int S, int T) {
    int res = 0;
    while (bfs(S, T)) {
        res += dfs(S, T, inf);
    }
    return res;
}

void add_edge(int x, int y, int w) {
    nxt[++e_tot] = head[x], head[x] = e_tot, to[e_tot] = y, c[e_tot] = w;
    nxt[++e_tot] = head[y], head[y] = e_tot, to[e_tot] = x, c[e_tot] = 0;
}

void solve() {
    int n, k;
    scanf("%d%d", &n, &k);
    for (int i = 1; i <= n; ++i) {
        scanf("%d", &C[i]);
    }
    sort(C + 1, C + n + 1);
    cnt1 = 0;
    for (int i = 1; i <= n; ++i) {
        if (C[i] == 1) ++cnt1;
        else if (C[i] & 1) {
            if (C[i] == a[na]) {
                ++cnta[na];
            }
            else {
                a[++na] = C[i];
                cnta[na] = 1;
            }
        }
        else {
            if (C[i] == b[nb]) {
                ++cntb[nb];
            }
            else {
                b[++nb] = C[i];
                cntb[nb] = 1;
            }
        }
    }
    // int S = na + nb + 1, 
    S = na + nb + 1, T = na + nb + 2;
    for (int i = 1; i <= na; ++i) {
        add_edge(S, i, cnta[i]);
    }
    for (int i = 1; i <= nb; ++i) {
        add_edge(na + i, T, cntb[i]);
    }
    for (int i = 1; i <= na; ++i) {
        for (int j = 1; j <= nb; ++j) {
            if (!vis[a[i] + b[j]]) {
                add_edge(i, na + j, inf);
                visa[i] = visb[j] = 1;
            }
        }
    }
    for (int i = 1; i <= nb; ++i) {
        if (cnt1 && !vis[b[i] + 1]) visb[i] = 1;
    }
    int cnt = 0;
    for (int i = 1; i <= na; ++i) {
        if (visa[i]) cnt += cnta[i];
    }
    for (int i = 1; i <= nb; ++i) {
        if (visb[i]) cnt += cntb[i];
    }
    int vis1 = 0;
    int res1 = dinic(S, T);
    add_edge(S, na + nb + 3, cnt1);
    for (int i = 1; i <= nb; ++i) {
        if (!vis[b[i] + 1]) {
            vis1 = 1;
            add_edge(na + nb + 3, na + i, inf);
        }
    }
    if (cnt1 >= 2) vis1 = 1;
    int res2 = dinic(S, T);
    // cerr << res1 << ' ' << res2 << '\n';
    int ans = 0;
    ans += 2 * (res2 + res1);
    
    ans += (cnt1 - res2) / 2 * 2;
    
    // k -= ans / 2;
    if (k < ans / 2) {
        ans = 2 * k;
        k = 0;
    }
    else k -= ans / 2;
    
    if ((cnt1 - res2) % 2 == 1 && vis1) {
        // &&
        if (k > 0) {
            ++ans;
            --k;
        }
    }
    if (k > 0) {
        cnt -= 2 * res1 + res2;
        // cerr << ans << ' ' << cnt << '\n';
        ans += min(cnt, k);
    }
    printf("%d\n", ans);
    for (int i = 0; i <= e_tot; ++i) {
        to[i] = nxt[i] = c[i] = 0;
    }
    for (int i = 1; i <= na + nb + 3; ++i) {
        head[i] = cur[i] = dep[i] = 0;
    }
    for (int i = 1; i <= n; ++i) {
        visa[i] = visb[i] = cnta[i] = cntb[i] = 0;
    }
    na = nb = cnt1 = 0;
    e_tot = 1;
    // if (res2 - res1 >= )
}

int main() {
    for (int i = 2; i <= 2000000; ++i) {
        if (!vis[i]) pri[++ptot] = i;
        for (int j = 1; j <= ptot && i * pri[j] <= 2000000; ++j) {
            vis[i * pri[j]] = 1;
            if (i % pri[j] == 0) {
                break;
            }
        }
    }
    int T;
    scanf("%d", &T);
    while (T--) {
        solve();
    }
    return 0;
}

这程序好像有点Bug,我给组数据试试?

詳細信息

Test #1:

score: 100
Accepted
time: 10ms
memory: 18980kb

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: 51ms
memory: 24484kb

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