QOJ.ac
QOJ
ID | 提交记录ID | 题目 | Hacker | Owner | 结果 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|
#971 | #639667 | #9457. Prime Set | hos_lyric | ucup-team159 | Failed. | 2024-10-13 21:45:51 | 2024-10-13 21:45:53 |
詳細信息
Extra Test:
Accepted
time: 304ms
memory: 56284kb
input:
4 3000 1499 41 42 251 252 461 462 671 672 881 882 1091 1092 1301 1302 1511 1512 1721 1722 1931 1932 2141 2142 2351 2352 2561 2562 2771 2772 2981 2982 3191 3192 3401 3402 3611 3612 3821 3822 4031 4032 4241 4242 4451 4452 4661 4662 4871 4872 5081 5082 5291 5292 5501 5502 5711 5712 5921 5922 6131 6132 ...
output:
2998 3000 3000 1000
result:
ok 4 lines
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#639667 | #9457. Prime Set | ucup-team159 | AC ✓ | 109ms | 28012kb | C++23 | 9.2kb | 2024-10-13 21:16:54 | 2024-10-13 21:16:55 |
answer
#line 1 "H.cpp"
// #pragma GCC target("avx2,avx512f,avx512vl,avx512bw,avx512dq,avx512cd,avx512vbmi,avx512vbmi2,avx512vpopcntdq,avx512bitalg,bmi,bmi2,lzcnt,popcnt")
// #pragma GCC optimize("Ofast")
#line 2 "/home/sigma/comp/library/template.hpp"
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using uint = unsigned int;
using ull = unsigned long long;
#define rep(i,n) for(int i=0;i<int(n);i++)
#define rep1(i,n) for(int i=1;i<=int(n);i++)
#define per(i,n) for(int i=int(n)-1;i>=0;i--)
#define per1(i,n) for(int i=int(n);i>0;i--)
#define all(c) c.begin(),c.end()
#define si(x) int(x.size())
#define pb push_back
#define eb emplace_back
#define fs first
#define sc second
template<class T> using V = vector<T>;
template<class T> using VV = vector<vector<T>>;
template<class T,class U> bool chmax(T& x, U y){
if(x<y){ x=y; return true; }
return false;
}
template<class T,class U> bool chmin(T& x, U y){
if(y<x){ x=y; return true; }
return false;
}
template<class T> void mkuni(V<T>& v){sort(all(v));v.erase(unique(all(v)),v.end());}
template<class T> int lwb(const V<T>& v, const T& a){return lower_bound(all(v),a) - v.begin();}
template<class T>
V<T> Vec(size_t a) {
return V<T>(a);
}
template<class T, class... Ts>
auto Vec(size_t a, Ts... ts) {
return V<decltype(Vec<T>(ts...))>(a, Vec<T>(ts...));
}
template<class S,class T> ostream& operator<<(ostream& o,const pair<S,T> &p){
return o<<"("<<p.fs<<","<<p.sc<<")";
}
template<class T> ostream& operator<<(ostream& o,const vector<T> &vc){
o<<"{";
for(const T& v:vc) o<<v<<",";
o<<"}";
return o;
}
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n-1); }
#ifdef LOCAL
#define show(x) cerr << "LINE" << __LINE__ << " : " << #x << " = " << (x) << endl
void dmpr(ostream& os){os<<endl;}
template<class T,class... Args>
void dmpr(ostream&os,const T&t,const Args&... args){
os<<t<<" ~ ";
dmpr(os,args...);
}
#define shows(...) cerr << "LINE" << __LINE__ << " : ";dmpr(cerr,##__VA_ARGS__)
#define dump(x) cerr << "LINE" << __LINE__ << " : " << #x << " = {"; \
for(auto v: x) cerr << v << ","; cerr << "}" << endl;
#else
#define show(x) void(0)
#define dump(x) void(0)
#define shows(...) void(0)
#endif
template<class D> D divFloor(D a, D b){
return a / b - (((a ^ b) < 0 && a % b != 0) ? 1 : 0);
}
template<class D> D divCeil(D a, D b) {
return a / b + (((a ^ b) > 0 && a % b != 0) ? 1 : 0);
}
#line 1 "/home/sigma/comp/ac-library/atcoder/maxflow.hpp"
#line 9 "/home/sigma/comp/ac-library/atcoder/maxflow.hpp"
#line 1 "/home/sigma/comp/ac-library/atcoder/internal_queue.hpp"
#line 5 "/home/sigma/comp/ac-library/atcoder/internal_queue.hpp"
namespace atcoder {
namespace internal {
template <class T> struct simple_queue {
std::vector<T> payload;
int pos = 0;
void reserve(int n) { payload.reserve(n); }
int size() const { return int(payload.size()) - pos; }
bool empty() const { return pos == int(payload.size()); }
void push(const T& t) { payload.push_back(t); }
T& front() { return payload[pos]; }
void clear() {
payload.clear();
pos = 0;
}
void pop() { pos++; }
};
} // namespace internal
} // namespace atcoder
#line 11 "/home/sigma/comp/ac-library/atcoder/maxflow.hpp"
namespace atcoder {
template <class Cap> struct mf_graph {
public:
mf_graph() : _n(0) {}
explicit mf_graph(int n) : _n(n), g(n) {}
int add_edge(int from, int to, Cap cap) {
assert(0 <= from && from < _n);
assert(0 <= to && to < _n);
assert(0 <= cap);
int m = int(pos.size());
pos.push_back({from, int(g[from].size())});
int from_id = int(g[from].size());
int to_id = int(g[to].size());
if (from == to) to_id++;
g[from].push_back(_edge{to, to_id, cap});
g[to].push_back(_edge{from, from_id, 0});
return m;
}
struct edge {
int from, to;
Cap cap, flow;
};
edge get_edge(int i) {
int m = int(pos.size());
assert(0 <= i && i < m);
auto _e = g[pos[i].first][pos[i].second];
auto _re = g[_e.to][_e.rev];
return edge{pos[i].first, _e.to, _e.cap + _re.cap, _re.cap};
}
std::vector<edge> edges() {
int m = int(pos.size());
std::vector<edge> result;
for (int i = 0; i < m; i++) {
result.push_back(get_edge(i));
}
return result;
}
void change_edge(int i, Cap new_cap, Cap new_flow) {
int m = int(pos.size());
assert(0 <= i && i < m);
assert(0 <= new_flow && new_flow <= new_cap);
auto& _e = g[pos[i].first][pos[i].second];
auto& _re = g[_e.to][_e.rev];
_e.cap = new_cap - new_flow;
_re.cap = new_flow;
}
Cap flow(int s, int t) {
return flow(s, t, std::numeric_limits<Cap>::max());
}
Cap flow(int s, int t, Cap flow_limit) {
assert(0 <= s && s < _n);
assert(0 <= t && t < _n);
assert(s != t);
std::vector<int> level(_n), iter(_n);
internal::simple_queue<int> que;
auto bfs = [&]() {
std::fill(level.begin(), level.end(), -1);
level[s] = 0;
que.clear();
que.push(s);
while (!que.empty()) {
int v = que.front();
que.pop();
for (auto e : g[v]) {
if (e.cap == 0 || level[e.to] >= 0) continue;
level[e.to] = level[v] + 1;
if (e.to == t) return;
que.push(e.to);
}
}
};
auto dfs = [&](auto self, int v, Cap up) {
if (v == s) return up;
Cap res = 0;
int level_v = level[v];
for (int& i = iter[v]; i < int(g[v].size()); i++) {
_edge& e = g[v][i];
if (level_v <= level[e.to] || g[e.to][e.rev].cap == 0) continue;
Cap d =
self(self, e.to, std::min(up - res, g[e.to][e.rev].cap));
if (d <= 0) continue;
g[v][i].cap += d;
g[e.to][e.rev].cap -= d;
res += d;
if (res == up) return res;
}
level[v] = _n;
return res;
};
Cap flow = 0;
while (flow < flow_limit) {
bfs();
if (level[t] == -1) break;
std::fill(iter.begin(), iter.end(), 0);
Cap f = dfs(dfs, t, flow_limit - flow);
if (!f) break;
flow += f;
}
return flow;
}
std::vector<bool> min_cut(int s) {
std::vector<bool> visited(_n);
internal::simple_queue<int> que;
que.push(s);
while (!que.empty()) {
int p = que.front();
que.pop();
visited[p] = true;
for (auto e : g[p]) {
if (e.cap && !visited[e.to]) {
visited[e.to] = true;
que.push(e.to);
}
}
}
return visited;
}
private:
int _n;
struct _edge {
int to, rev;
Cap cap;
};
std::vector<std::pair<int, int>> pos;
std::vector<std::vector<_edge>> g;
};
} // namespace atcoder
#line 6 "H.cpp"
using namespace atcoder;
V<bool> isp;
V<int> pr;
V<int> sf; //smallest factor, sf[9*5*11] = 3
void linear_sieve(int X){ // <= X
isp = V<bool>(X+1,true); isp[0] = isp[1] = false;
sf = V<int>(X+1);
pr.clear();
for(int i=2;i<=X;i++){
if(isp[i]){
pr.pb(i);
sf[i] = i;
}
for(int j=0;i*pr[j]<=X;j++){
isp[i*pr[j]] = false;
sf[i*pr[j]] = pr[j];
if(i%pr[j] == 0) break;
}
}
}
int solve(){
int N,K; cin >> N >> K;
map<int,int> even,odd;
rep(i,N){
int a; cin >> a;
if(a%2 == 0) even[a]++;
else odd[a]++;
}
int E = si(even), O = si(odd);
mf_graph<int> G(E+O+2);
int S = E+O, T = E+O+1;
int one_idx = -1;
{
int i = 0;
for(auto [v,c]: even){
G.add_edge(S,i,c);
i++;
}
}
{
int i = 0;
for(auto [v,c]: odd){
if(v != 1) G.add_edge(E+i,T,c);
i++;
}
}
set<int> st;
{
int i = 0;
for(auto [v,c]: even){
int j = 0;
for(auto [w,d]: odd){
if(isp[v+w]){
G.add_edge(i,E+j,min(c,d));
st.insert(v); st.insert(w);
}
j++;
}
i++;
}
}
int X = 0; // max
for(auto v: st){
if(v%2 == 0) X += even[v];
else X += odd[v];
}
if(!st.count(1) && odd.count(1) && odd[1] >= 2) X += odd[1];
show(X);
int f0 = G.flow(S,T);
{
int i = 0;
for(auto [v,c]: odd){
if(v == 1){
one_idx = G.add_edge(E+i,T,c);
}
i++;
}
}
int f1 = G.flow(S,T);
int f = f0 + f1;
show(f0); show(f1);
if(one_idx != -1){
int used_one = G.get_edge(one_idx).flow;
int num_one = odd[1];
show(used_one); show(num_one);
int f2 = (num_one - used_one) / 2;
f += f2;
}
chmin(f,K);
return min(f+K, X);
}
int main(){
cin.tie(0);
ios::sync_with_stdio(false); //DON'T USE scanf/printf/puts !!
cout << fixed << setprecision(20);
linear_sieve(2e6);
int T; cin >> T;
while(T--) cout << solve() << endl;
}