QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#309137 | #7524. A Challenge For a Tourist | 8BQube# | WA | 2ms | 7900kb | C++20 | 3.6kb | 2024-01-20 15:04:11 | 2024-01-20 15:04:11 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
#define X first
#define Y second
#define SZ(a) ((int)a.size())
#define ALL(v) v.begin(), v.end()
#define pb push_back
const int INF = 2e9;
struct Edge {
int u, v, w;
bool operator<(const Edge &e) const {
return w < e.w;
}
} edges[200005];
struct Basis {
vector<int> basis;
void insert(int x) {
for (int i : basis)
x = min(x, x ^ i);
if (x > 0)
basis.pb(x);
}
bool check(int x) {
for (int i : basis)
x = min(x, x ^ i);
return x == 0;
}
void Union(const Basis &b) {
for (int i : b.basis)
insert(i);
}
} basis[200005];
vector<pii> G[200005];
vector<Basis> version[200005];
vector<int> timing[200005];
int depth[200005], boss[200005], sz[200005], up[200005];
int finds(int x) {
while (x != boss[x]) x = boss[x];
return x;
}
bool Union(int u, int v, int w, int type) {
if (finds(u) == finds(v)) return false;
if (type == 0) {
G[u].pb(pii(v, w));
G[v].pb(pii(u, w));
}
u = finds(u), v = finds(v);
if (sz[u] > sz[v]) swap(u, v);
boss[u] = v;
up[u] = w;
sz[v] += sz[v];
if (type == 1) {
version[v].pb(version[v].back());
timing[v].pb(w);
version[v].back().Union(version[u].back());
}
return true;
}
void dfs(int u, int f, int d) {
depth[u] = d;
for (auto [v, w] : G[u])
if (v != f)
dfs(v, u, d ^ w);
}
int main() {
ios::sync_with_stdio(0), cin.tie(0);
int n, m;
cin >> n >> m;
for (int i = 1; i <= m; ++i)
cin >> edges[i].u >> edges[i].v >> edges[i].w;
sort(edges + 1, edges + m + 1);
iota(boss + 1, boss + n + 1, 1);
fill_n(sz + 1, n, 1);
for (int i = 1; i <= m; ++i)
Union(edges[i].u, edges[i].v, edges[i].w, 0);
for (int i = 1; i <= n; ++i)
if (finds(i) == i)
dfs(i, i, 0);
iota(boss + 1, boss + n + 1, 1);
fill_n(sz + 1, n, 1);
fill_n(up + 1, n, INF);
for (int i = 1; i <= n; ++i)
version[i].pb(Basis()), timing[i].pb(-1);
for (int i = 1; i <= m; ++i) {
if (!Union(edges[i].u, edges[i].v, edges[i].w, 1)) {
int r = finds(edges[i].u);
version[r].pb(version[r].back()), version[r].back().insert(depth[edges[i].u] ^ depth[edges[i].v] ^ edges[i].w);
timing[r].pb(edges[i].w);
}
}
int q;
cin >> q;
while (q--) {
int u, v, w;
cin >> u >> v >> w;
if (finds(u) != finds(v)) {
cout << "-1\n";
continue;
}
int path = depth[u] ^ depth[v], lower = 0;
while (u != v) {
if (sz[u] > sz[v]) swap(u, v);
lower = max(lower, up[u]);
u = boss[u];
}
auto check = [&](int t) {
if (t < lower) return false;
int cur = u;
while (t >= up[cur]) cur = boss[cur];
int p = lower_bound(ALL(timing[cur]), t) - timing[cur].begin();
if (p == SZ(version[cur])) --p;
return version[cur][p].check(path ^ w);
};
int l = 1, r = m + 1;
while (l < r) {
int mid = (l + r) >> 1;
if (check(edges[mid].w)) r = mid;
else l = mid + 1;
}
if (l == m + 1) cout << "-1\n";
else cout << edges[l].w << "\n";
}
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 2ms
memory: 7900kb
input:
6 6 5 6 3 6 2 2 1 2 1 2 3 2 2 4 3 4 5 4 3 1 3 1 1 3 3 1 3 5
output:
-1 2 4
result:
ok 3 number(s): "-1 2 4"
Test #2:
score: 0
Accepted
time: 2ms
memory: 7648kb
input:
2 1 1 2 1 1 1 2 1
output:
1
result:
ok 1 number(s): "1"
Test #3:
score: -100
Wrong Answer
time: 2ms
memory: 7900kb
input:
5 10 1 2 4 2 2 0 1 1 7 2 1 7 4 1 1 5 5 1 4 1 4 5 2 6 1 1 2 2 4 7 10 1 4 3 1 2 5 3 2 1 3 5 5 2 4 0 3 2 0 2 1 2 2 3 6 5 1 7 2 3 3
output:
2 6 -1 -1 6 -1 6 -1 6 -1
result:
wrong answer 5th numbers differ - expected: '4', found: '6'