QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#708950 | #9449. New School Term | _rey | WA | 0ms | 3804kb | C++17 | 3.6kb | 2024-11-04 10:07:17 | 2024-11-04 10:07:18 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
class union_find {
private:
vector<int> rep, sz;
int find(int u) { return rep[u] == u ? u : rep[u] = find(rep[u]); }
public:
union_find(int n, bool b = false) : rep (n), sz (n) {
for (int i = 0; i < n; ++i)
rep[i] = i, sz[i] = b ? i%2 : 1;
}
void une(int u, int v) {
u = find(u);
v = find(v);
if (sz[u] > sz[v]) swap(u, v);
rep[u] = v;
sz[v] += sz[u];
}
bool same(int u, int v) { return find(u) == find(v); }
int size(int u) { return sz[find(u)]; }
};
class bipart_uf {
private:
union_find U, B;
public:
bipart_uf(int n) : U (n), B (2*n, true) { }
int status(int u, int v) {
if (!U.same(u, v)) return 1;
if (B.same(2*u, 2*v + 1)) return 0;
return -1;
}
void une(int u, int v, bool b) {
U.une(u, v);
B.une(2*u, 2*v + !b);
B.une(2*u + 1, 2*v + b);
}
pair<int, int> size(int u) { return {B.size(2*u + 1), B.size(2*u)}; }
};
template<int MOD>
class subset_sum {
private:
vector<int> cnt; int sz, target;
public:
subset_sum(int n) : cnt (n + 1), sz (n), target (n) {
cnt[0] = 1;
}
void add(int a, int b) {
if (a < b) swap(a, b);
target -= b;
int val = a - b;
for (int i = sz; i >= val; --i)
cnt[i] = (cnt[i] + cnt[i - val])%MOD;
}
void erase(int a, int b) {
if (a < b) swap(a, b);
target += b;
int val = a - b;
if (val > 0)
for (int i = val; i <= sz; ++i)
cnt[i] = (cnt[i] - cnt[i - val] + MOD)%MOD;
else
for (int i = val; i <= sz; ++i)
cnt[i] = cnt[i]%2 == 0 ? cnt[i]/2 : (cnt[i] + MOD)/2;
}
bool valid() { return target >= 0 && cnt[target] > 0; }
};
int main() {
int n, m;
cin >> n >> m;
n *= 2;
vector<pair<int, int>> edges(m);
for (auto &[u, v]: edges) {
cin >> u >> v;
--u; --v;
}
subset_sum<1000000009> S(n/2);
for (int i = 0; i < n; ++i)
S.add(1, 0);
bipart_uf B(n);
vector<bool> got(m);
for (int i = m - 1; i >= 0; --i) {
auto [u, v] = edges[i];
int flag = B.status(u, v);
if (flag == -1) {
got[i] = 1;
continue;
}
if (flag == 0) continue;
auto [a1, b1] = B.size(u);
auto [a2, b2] = B.size(v);
S.erase(a1, b1); S.erase(a2, b2);
S.add(a1 + b2, a2 + b1);
if (!S.valid()) {
got[i] = 1;
S.erase(a1 + b2, a2 + b1);
S.add(a1 + a2, b1 + b2);
B.une(u, v, true);
}
else B.une(u, v, false);
}
vector<vector<pair<int, int>>> graph(n);
for (int i = 0; i < m; ++i) {
auto [u, v] = edges[i];
graph[u].emplace_back(v, i);
graph[v].emplace_back(u, i);
}
vector<int> marc(n);
function<pair<int, int> (int, int)> dfs = [&](int u, int c) {
marc[u] = c;
pair<int, int> ans{1, 0};
for (auto [v, i]: graph[u]) if (!marc[v])
if (!got[i]) {
auto [a, b] = dfs(v, -c);
ans.first += b; ans.second += a;
}
else {
auto [a, b] = dfs(v, c);
ans.first += a; ans.second += b;
}
return ans;
};
vector<pair<int, int>> costs; int comps = 0;
for (int i = 0; i < n; ++i) if (!marc[i])
costs.push_back(dfs(i, ++comps));
vector<bool> pos(n/2 + 1);
pos[0] = true;
for (auto [a, b]: costs)
for (int i = n/2; i >= 0; --i)
pos[i] = pos[i]
|| (i >= a ? pos[i - a]: false)
|| (i >= b ? pos[i - b]: false);
vector<bool> invert(costs.size());
int atual = n/2;
for (int i = costs.size() - 1; i >= 0; --i) {
auto [a, b] = costs[i];
if (pos[atual - a]) atual -= a;
else { atual -= b; invert[i] = true; }
}
for (int i = 0; i < n; ++i)
cout << ((marc[i] > 0) ^ (invert[abs(marc[i])]));
cout << "\n";
}
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 3772kb
input:
2 4 1 3 2 4 1 4 1 2
output:
1010
result:
ok Output is valid. OK
Test #2:
score: 0
Accepted
time: 0ms
memory: 3804kb
input:
3 7 2 5 1 3 4 6 2 6 4 5 2 4 5 6
output:
110010
result:
ok Output is valid. OK
Test #3:
score: -100
Wrong Answer
time: 0ms
memory: 3580kb
input:
1 0
output:
11
result:
wrong answer The number of 0s must be equal to that of 1s.