QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#106619 | #6402. MEXimum Spanning Tree | tom0727 | WA | 1ms | 4348kb | C++14 | 6.0kb | 2023-05-18 12:15:05 | 2023-05-18 12:15:52 |
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;
} st[maxm]; // 注意这里是 maxm,应该是边的数量
int uni = 0; // union 的次数,如果等于 n-1 说明联通了
int n, m, k;
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) {
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]}; // 无论是否 union 成功都要push到 stack 里
if (u == v) return;
par[v] = u;
sz[u] += sz[v];
uni++; // 成功union
}
void cancel() {
if (tail > 0) {
int u = st[tail].u, v = st[tail].v;
par[v] = v;
if (sz[u] != st[tail].szu) uni--; // 成功回退一次union
sz[u] = st[tail].szu;
sz[v] = st[tail].szv;
tail--;
}
}
} dsu;
struct Edge {
int u, v, w;
};
struct TreeNode {
vector<Edge> vec;
};
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) {
for (Edge& e : tr[cur].vec) {
dsu.unions(e.u, e.v);
dsu.unions(e.u, e.v);
}
if (l == r) {
if (uni == n-1) 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;
for (int i = 1; i <= m; i++) {
int u, v, w; cin >> 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});
}
tr.dfs(1, 0, N);
cout << ans << "\n";
}
詳細信息
Test #1:
score: 0
Wrong Answer
time: 1ms
memory: 4348kb
input:
4 4 1 2 0 2 3 1 1 3 1 3 4 2
output:
1000
result:
wrong answer 1st numbers differ - expected: '3', found: '1000'