QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#633390#9457. Prime Setucup-team3519#AC ✓55ms23012kbC++174.3kb2024-10-12 15:14:112024-10-13 19:27:41

Judging History

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

  • [2024-10-13 19:27:41]
  • 自动重测本题所有获得100分的提交记录
  • 测评结果:AC
  • 用时:55ms
  • 内存:23012kb
  • [2024-10-13 19:27:24]
  • hack成功,自动添加数据
  • (/hack/967)
  • [2024-10-13 18:38:32]
  • 管理员手动重测本题所有得分≥97分的提交记录
  • 测评结果:100
  • 用时:42ms
  • 内存:24180kb
  • [2024-10-13 18:24:51]
  • hack成功,自动添加数据
  • (/hack/965)
  • [2024-10-13 18:17:54]
  • hack成功,自动添加数据
  • (/hack/963)
  • [2024-10-12 15:14:11]
  • 评测
  • 测评结果:100
  • 用时:32ms
  • 内存:22972kb
  • [2024-10-12 15:14:11]
  • 提交

answer

#include <bits/stdc++.h>

template <class T>
struct Flow {
    static constexpr int INF = 1e9;
    int n;
    struct Edge {
        int to;
        T cap;
        Edge(int to, T cap) : to(to), cap(cap) {}
    };
    std::vector<Edge> edge;
    std::vector<std::vector<int>> adj;
    std::vector<int> cur, dep;
    explicit Flow(int n) : n(n), adj(n) {}
    bool bfs(int s, int t) {
        dep.assign(n, -1);
        std::queue<int> q;
        dep[s] = 0;
        q.push(s);
        while (!q.empty()) {
            int node = q.front();
            q.pop();
            for (int i : adj[node]) {
                int to = edge[i].to;
                T c = edge[i].cap;
                if (c > 0 && dep[to] == -1) {
                    dep[to] = dep[node] + 1;
                    if (to == t) {
                        return true;
                    }
                    q.push(to);
                }
            }
        }
        return false;
    }
    T dfs(int node, int t, T flow) {
        if (node == t || flow == 0) {
            return flow;
        }
        T f, res = 0;
        for (int &i = cur[node]; i < int(adj[node].size()); ++i) {
            int j = adj[node][i];
            int to = edge[j].to;
            T c = edge[j].cap;

            if (dep[to] == dep[node] + 1 && 
                (f = dfs(to, t, std::min(flow, c)))) {
                res += f;
                flow -= f;
                edge[j].cap -= f;
                edge[j ^ 1].cap += f;
            }

            if (flow == 0) {
                break;
            }
        }
        if (!res) {
            dep[node] = -1;
        }
        return res;
    }
    int add_edge(int u, int v, T c) {
        int j = edge.size();
        adj[u].push_back(edge.size());
        edge.emplace_back(v, c);
        adj[v].push_back(edge.size());
        edge.emplace_back(u, 0);
        return j;
    }
    T operator()(int s, int t) {
        T ans = 0;
        while (bfs(s, t)) {
            cur.assign(n, 0);
            ans += dfs(s, t, INF);
        }
        return ans;
    }
};

constexpr int N = 2e6 + 19;

bool vist[N];
int prime[N], pcnt;

bool has_friend[N];
void solve() {
    int n, k;
    std::cin >> n >> k;

    std::map<int, int> count;
    for (int i = 0; i < n; ++i) {
        int x;
        std::cin >> x;
        count[x] += 1;
    }
    int c1 = count[1], e1 = 0;
    count[1] = 0;

    std::array<std::vector<int>, 2> a;
    for (auto [x, c] : count) {
        a[x & 1].push_back(x);
    }

    Flow<int> f(a[0].size() + a[1].size() + 2);
    const int s = f.n - 1, t = f.n - 2;

    for (int x = 0; x < a[0].size(); ++x) {
        f.add_edge(s, x, count[a[0][x]]);
    }
    for (int y = 0; y < a[1].size(); ++y) {
        int j = f.add_edge(a[0].size() + y, t, count[a[1][y]]);
        if (a[1][y] == 1) {
            e1 = j;
        }
    }
    for (int x = 0; x < a[0].size(); ++x) {
        for (int y = 0; y < a[1].size(); ++y) {
            if (!vist[a[0][x] + a[1][y]]) {
                f.add_edge(x, a[0].size() + y, Flow<int>::INF);
                if (a[1][y] != 1 || c1) {
                    has_friend[a[0][x]] = true;
                    has_friend[a[1][y]] = true;
                }
            }
        }
    }
    if (c1 >= 2) {
        has_friend[1] = true;
    }

    int matching = f(s, t);
    count[1] = c1;
    f.edge[e1].cap += c1;
    matching += f(s, t);
    matching += f.edge[e1].cap / 2;

    int tot = 0;
    for (auto [x, c] : count) {
        if (has_friend[x]) {
            tot += c;
        }
        has_friend[x] = false;
    }

    if (k <= matching) {
        std::cout << k * 2 << '\n';
    } else {
        int ans = matching * 2 + (k - matching);
        ans = std::min(ans, tot);
        std::cout << ans << '\n';
    }
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    for (int i = 2; i < N; ++i) {
        if (!vist[i]) {
            prime[++pcnt] = i;
        }
        for (int j = 1; j <= pcnt && i * prime[j] < N; ++j) {
            vist[i * prime[j]] = true;
            if (i % prime[j] == 0) {
                break;
            }
        }
    }
    
    int t;
    std::cin >> t;

    while (t--) {
        solve();
    }
}

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

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 9ms
memory: 7872kb

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: 55ms
memory: 23012kb

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