QOJ.ac
QOJ
The 2nd Universal Cup Finals is coming! Check out our event page, schedule, and competition rules!
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#106630 | #6402. MEXimum Spanning Tree | tom0727 | WA | 10ms | 4672kb | C++14 | 7.0kb | 2023-05-18 12:55:08 | 2023-05-18 12:55:11 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
#if __cplusplus >= 201103L
struct pairhash {
static uint64_t splitmix64(uint64_t x) {
x += 0x9e3779b97f4a7c15;
x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
return x ^ (x >> 31);
}
template<class T, class U>
size_t operator() (const pair<T,U> &p) const {
static const uint64_t FIXED_RANDOM = (uint64_t)chrono::steady_clock::now().time_since_epoch().count();
return splitmix64(p.first + FIXED_RANDOM) ^ splitmix64(p.second+ FIXED_RANDOM);
}
};
struct custom_hash {
static uint64_t splitmix64(uint64_t x) {
x += 0x9e3779b97f4a7c15;
x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
return x ^ (x >> 31);
}
size_t operator()(uint64_t x) const {
static const uint64_t FIXED_RANDOM = (uint64_t)chrono::steady_clock::now().time_since_epoch().count();
return splitmix64(x + FIXED_RANDOM);
}
};
mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());
inline int randint(int l, int r) {
return uniform_int_distribution<int>(l,r)(rng);
}
inline double randdouble(double l, double r) {
return uniform_real_distribution<double>(l,r)(rng);
}
#endif
#ifndef ONLINE_JUDGE
# define LOG(x) (cerr << #x << " = " << (x) << endl)
#else
# define LOG(x) 0
#endif
#define fastio ios::sync_with_stdio(false); cin.tie(0);
#define ll long long
#define ull unsigned long long
#define ll128 __int128_t
#define PI 3.14159265358979323846
#define abs(a) ((a>0)?a:-(a))
#define pii pair<int,int>
#define pll pair<ll,ll>
const long double pi = acos(-1.0);
const long double eps = (double)1e-2;
int mod = (1<<30);
template<class T>
T qpow(T a, int b) {
T res = 1;
while (b) {
if (b & 1) res *= a;
a *= a;
b >>= 1;
}
return res;
}
int norm(int x) {
if (x < 0) {
x += mod;
}
if (x >= mod) {
x -= mod;
}
return x;
}
struct Z {
int x;
Z(int x = 0) : x(norm(x)) {}
Z(ll x) : x(norm((int)(x % mod))) {}
int val() const {
return x;
}
Z operator-() const {
return Z(norm(mod - x));
}
Z inv() const {
assert(x != 0);
return qpow(*this, mod - 2);
}
Z &operator*=(const Z &rhs) {
x = (ll)(x) * rhs.x % mod;
return *this;
}
Z &operator+=(const Z &rhs) {
x = norm(x + rhs.x);
return *this;
}
Z &operator-=(const Z &rhs) {
x = norm(x - rhs.x);
return *this;
}
Z &operator/=(const Z &rhs) {
return *this *= rhs.inv();
}
friend Z operator*(const Z &lhs, const Z &rhs) {
Z res = lhs;
res *= rhs;
return res;
}
friend Z operator+(const Z &lhs, const Z &rhs) {
Z res = lhs;
res += rhs;
return res;
}
friend Z operator-(const Z &lhs, const Z &rhs) {
Z res = lhs;
res -= rhs;
return res;
}
friend Z operator/(const Z &lhs, const Z &rhs) {
Z res = lhs;
res /= rhs;
return res;
}
friend std::istream &operator>>(std::istream &is, Z &a) {
ll v;
is >> v;
a = Z(v);
return is;
}
friend std::ostream &operator<<(std::ostream &os, const Z &a) {
return os << a.val();
}
};
const int maxn = 1e4+5;
const int maxm = 4e4+55;
struct State {
int u, v, szu, szv, w;
} st[maxm]; // 注意这里是 maxm,应该是边的数量
int uni = 0; // union 的次数,如果等于 n-1 说明联通了
int n, m, k;
multiset<int> ms;
struct DSU {
int par[maxn], sz[maxn], tail = 0;
inline void init() {
for (int i = 1; i <= n; i++) par[i] = i, sz[i] = 1;
tail = 0;
}
int finds(int u) {
if (par[u] == u) return u;
return finds(par[u]); // 无路径压缩
}
void unions(int u, int v, int w) {
u = finds(u), v = finds(v);
if (sz[u] < sz[v]) swap(u,v); // sz[u] >= sz[v]
st[++tail] = {u, v, sz[u], sz[v], w}; // 无论是否 union 成功都要push到 stack 里
if (u == v) return;
par[v] = u;
sz[u] += sz[v];
uni++; // 成功union
// ms.insert({u, v, w});
ms.insert(w);
}
void cancel() {
if (tail > 0) {
int u = st[tail].u, v = st[tail].v, w = st[tail].w;
par[v] = v;
if (sz[u] != st[tail].szu) {
uni--; // 成功回退一次union
// ms.erase(ms.find(Edge {u, v, w}));
ms.erase(ms.find(w));
}
sz[u] = st[tail].szu;
sz[v] = st[tail].szv;
tail--;
}
}
} dsu;
struct Edge {
int u, v, w;
bool operator<(const Edge& other) const {
if (w == other.w) {
if (u == other.u) return v < other.v;
return u < other.u;
}
return w < other.w;
}
};
struct TreeNode {
vector<Edge> vec;
};
int mex() {
for (int i = 0; i <= 1000; i++) {
if (!ms.count(i)) return i;
}
}
int ans = 0;
struct SegmentTree {
TreeNode tr[maxn<<2];
void insert(int cur, int l, int r, int L, int R, Edge e) {
if (L <= l && R >= r) {
tr[cur].vec.push_back(e);
return;
}
int mid = (l+r) >> 1;
if (L <= mid) insert(cur<<1, l, mid, L, R, e);
if (R > mid) insert(cur<<1|1, mid+1, r, L, R, e);
}
void dfs(int cur, int l, int r) {
int pre = -1;
for (Edge& e : tr[cur].vec) {
dsu.unions(e.u, e.v, e.w);
assert(e.w >= pre);
pre = e.w;
// dsu.unions(e.u, e.v, e.w);
}
if (l == r) {
if (uni == n-1 && mex() == l) ans = max(ans, l);
} else {
int mid = (l+r) >> 1;
dfs(cur<<1, l, mid);
dfs(cur<<1|1, mid+1, r);
}
for (Edge& e : tr[cur].vec) {
dsu.cancel();
// dsu.cancel();
}
}
} tr;
int main() {
fastio;
cin >> n >> m;
dsu.init();
int N = 1e3;
vector<Edge> edges;
for (int i = 1; i <= m; i++) {
int u, v, w; cin >> u >> v >> w;
edges.push_back({u, v, w});
// if (w > 0)
// tr.insert(1, 0, N, 0, w-1, {u, v, w});
// if (w < N)
// tr.insert(1, 0, N, w+1, N, {u, v, w});
}
sort(edges.begin(), edges.end());
for (auto [u,v,w] : edges) {
if (w > 0)
tr.insert(1, 0, N, 0, w-1, {u, v, w});
if (w < N)
tr.insert(1, 0, N, w+1, N, {u, v, w});
}
tr.dfs(1, 0, N);
cout << ans << "\n";
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 2ms
memory: 4432kb
input:
4 4 1 2 0 2 3 1 1 3 1 3 4 2
output:
3
result:
ok 1 number(s): "3"
Test #2:
score: 0
Accepted
time: 10ms
memory: 4604kb
input:
1000 1000 647 790 6 91 461 435 90 72 74 403 81 240 893 925 395 817 345 136 88 71 821 831 962 53 164 270 298 14 550 317 99 580 81 26 477 488 977 474 861 413 483 167 872 675 17 819 327 449 594 242 68 381 983 319 867 582 358 869 225 669 274 352 392 40 388 998 246 477 44 508 979 286 483 776 71 580 438 6...
output:
502
result:
ok 1 number(s): "502"
Test #3:
score: -100
Wrong Answer
time: 7ms
memory: 4672kb
input:
900 1000 232 890 107 425 399 19 5 74 753 105 333 163 779 42 582 359 647 524 767 409 48 239 780 443 484 489 546 97 634 562 627 866 714 500 357 590 60 728 591 407 686 210 547 32 370 76 772 500 407 584 772 73 699 69 332 847 516 829 754 727 562 756 678 819 303 128 781 667 263 535 672 767 89 762 216 878 ...
output:
2
result:
wrong answer 1st numbers differ - expected: '801', found: '2'