QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#836417#9924. Reconstructionucup-team6275#WA 1337ms122252kbC++236.2kb2024-12-28 20:17:272024-12-28 20:17:29

Judging History

你现在查看的是最新测评结果

  • [2024-12-31 17:12:54]
  • hack成功,自动添加数据
  • (/hack/1320)
  • [2024-12-28 20:17:29]
  • 评测
  • 测评结果:WA
  • 用时:1337ms
  • 内存:122252kb
  • [2024-12-28 20:17:27]
  • 提交

answer

#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using ld = long double;
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define rep(i, n) for (int i = 0; i < (n); i += 1)
#define len(a) ((int)(a).size())

mt19937 rnd(234);
const ll inf = 1e18;

struct SGT {
    int n;
    vector<int> mn, mx;

    void build(int _n) {
        n = 1;
        while (n < _n) {
            n *= 2;
        }
        mn.assign(2 * n, 0);
        mx.assign(2 * n, 0);
    }

    void change(int i, int x) {
        i += n;
        mn[i] = mx[i] = x;
        for (i /= 2; i >= 1; i /= 2) {
            mn[i] = min(mn[i + i], mn[i + i + 1]);
            mx[i] = max(mx[i + i], mx[i + i + 1]);
        }
    }

    pair<int, int> get(int l, int r) {
        l += n;
        r += n + 1;
        int rsmn = 1e9;
        int rsmx = -1e9;
        while (l < r) {
            if (l & 1) {
                rsmn = min(rsmn, mn[l]);
                rsmx = max(rsmx, mx[l]);
                ++l;
            }
            if (r & 1) {
                --r;
                rsmn = min(rsmn, mn[r]);
                rsmx = max(rsmx, mx[r]);
            }
            l /= 2;
            r /= 2;
        }
        return make_pair(rsmn, rsmx);
    }
};

struct DSU {
    int n;
    vector<int> t;

    void build(int _n) {
        n = _n;
        t.resize(n);
        rep(i, n) {
            t[i] = i;
        }
    }

    int get(int v) {
        if (t[v] == v) {
            return v;
        }
        return (t[v] = get(t[v]));
    }

    void merge(int u, int v) {
        u = get(u);
        v = get(v);
        if (u == v) {
            return;
        }
        t[u] = v;
    }
};

int n;
vector<vector<int>> g1;
vector<vector<int>> g2;
vector<int> tin1, tout1;
vector<int> e1;
vector<int> tin2, tout2;
vector<int> e2;
vector<int> par1;
vector<int> par2;
vector<int> h2;
vector<int> gdup, gddown;

void dfs1(int v, int p) {
    par1[v] = p;
    tin1[v] = len(e1);
    e1.push_back(v);
    for (auto to : g1[v]) {
        if (to == p) {
            continue;
        }
        dfs1(to, v);
    }
    tout1[v] = len(e1);
}

void dfs2(int v, int p, int mh) {
    par2[v] = p;
    h2[v] = mh;
    tin2[v] = len(e2);
    e2.push_back(v);
    for (auto to : g2[v]) {
        if (to == p) {
            continue;
        }
        dfs2(to, v, mh + 1);
    }
    tout2[v] = len(e2);
}

void make_flex() {
    gdup.assign(n, false);
    gddown.assign(n, false);
    SGT sgt;
    sgt.build(n);
    rep(v, n) {
        sgt.change(tin2[v], tin1[v]);
    }
    for (auto v : e1) {
        vector<int> good_segs;
        for (auto to : g1[v]) {
            if (to != par1[v]) {
                good_segs.push_back(tin1[to]);
            }
        }
        good_segs.push_back(tout1[v]);
        good_segs.push_back(tin1[v] + n);
        sort(all(good_segs));
        auto check = [&](int to) {
            int mn, mx;
            if (to != par2[v]) {
                auto [mn1, mx1] = sgt.get(tin2[to], tout2[to] - 1);
                mn = mn1;
                mx = mx1;
            } else {
                auto [mn1, mx1] = sgt.get(0, tin2[v] - 1);
                auto [mn2, mx2] = sgt.get(tout2[v], n - 1);
                mn = min(mn1, mn2);
                mx = max(mx1, mx2);
            }
            int pos = upper_bound(all(good_segs), mx) - good_segs.begin();
            return pos < len(good_segs) and (pos == 0 or good_segs[pos - 1] <= mn);
        };
        for (auto to : g2[v]) {
            if (check(to)) {
                if (to != par2[v]) {
                    gddown[to] = true;
                } else {
                    gdup[v] = true;
                }
            }
        }
        sgt.change(tin2[v], tin1[v] + n);
    }
}

void dfs3(int v, int p, int cnt_good, vector<int> &result) {
    if (cnt_good == n - 1) {
        result[v] = true;
    }
    for (auto to : g2[v]) {
        if (to == p) {
            continue;
        }
        dfs3(to, v, cnt_good - gddown[to] + gdup[to], result);
    }
}

void check_result(vector<int> &result) {
    DSU dsu;
    dsu.build(n);
    auto mark_way = [&](int a, int b) {
        int u = a;
        int v = b;
        u = dsu.get(u);
        v = dsu.get(v);
        while (u != v) {
            if (h2[u] > h2[v]) {
                if (u != a and u != b) {
                    result[u] = false;
                    dsu.merge(u, par2[u]);
                    u = dsu.get(u);
                } else {
                    u = dsu.get(par2[u]);
                }
            } else {
                if (v != a and v != b) {
                    result[v] = false;
                    dsu.merge(v, par2[v]);
                    v = dsu.get(v);
                } else {
                    v = dsu.get(par2[v]);
                }
            }
        }
        if (u != a and u != b) {
            result[u] = false;
            dsu.merge(u, par2[u]);
        }
    };
    rep(v, n) {
        for (auto to : g1[v]) {
            if (v < to) {
                mark_way(v, to);
            }
        }
    }
}

int32_t main() {
    if (1) {
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
    }
    cin >> n;
    g1.assign(n, {});
    rep(i, n - 1) {
        int u, v;
        cin >> u >> v;
        --u;
        --v;
        g1[u].push_back(v);
        g1[v].push_back(u);
    }
    g2.assign(n, {});
    rep(i, n - 1) {
        int u, v;
        cin >> u >> v;
        --u;
        --v;
        g2[u].push_back(v);
        g2[v].push_back(u);
    }
    tin1.resize(n);
    tout1.resize(n);
    par1.resize(n);
    e1.clear();
    e1.reserve(n);
    dfs1(0, 0);
    tin2.resize(n);
    tout2.resize(n);
    par2.resize(n);
    e2.clear();
    e2.reserve(n);
    h2.resize(n);
    dfs2(0, 0, 0);
    make_flex();
    vector<int> result(n, false);
    int cnt_good = 0;
    for (int v = 1; v < n; v += 1) {
        cnt_good += gddown[v];
    }
    dfs3(0, 0, cnt_good, result);
    check_result(result);
    rep(v, n) {
        cout << result[v];
    }
    cout << "\n";
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 0ms
memory: 3828kb

input:

3
1 2
2 3
2 1
1 3

output:

001

result:

ok single line: '001'

Test #2:

score: 0
Accepted
time: 1ms
memory: 3636kb

input:

6
1 3
3 4
3 6
4 5
5 2
1 3
1 4
4 5
5 2
3 6

output:

010110

result:

ok single line: '010110'

Test #3:

score: 0
Accepted
time: 0ms
memory: 3580kb

input:

1

output:

1

result:

ok single line: '1'

Test #4:

score: 0
Accepted
time: 0ms
memory: 3860kb

input:

2
1 2
1 2

output:

11

result:

ok single line: '11'

Test #5:

score: -100
Wrong Answer
time: 1337ms
memory: 122252kb

input:

500000
321614 78209
64619 204431
81539 336200
128603 201377
132521 391792
41587 137224
174146 381680
341915 451206
493371 256005
259794 168656
161914 462290
105839 333679
377214 267008
283062 457340
219692 196741
123276 321510
473789 410796
498171 203543
178249 456921
255509 449152
294196 457566
277...

output:

000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000...

result:

wrong answer 1st lines differ - expected: '000000000000000000000000000000...0000000000000000000000000000000', found: '000000000000000000000000000000...0000000000000000000000000000000'