QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#106630#6402. MEXimum Spanning Treetom0727WA 10ms4672kbC++147.0kb2023-05-18 12:55:082023-05-18 12:55:11

Judging History

This is the latest submission verdict.

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-05-18 12:55:11]
  • Judged
  • Verdict: WA
  • Time: 10ms
  • Memory: 4672kb
  • [2023-05-18 12:55:08]
  • Submitted

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'