답안 #1093620

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1093620 2024-09-27T06:54:25 Z CDuong Inside information (BOI21_servers) C++17
80 / 100
266 ms 28936 KB
/*
#pragma GCC optimize("Ofast,unroll-loops")
#pragma GCC target("avx2,fma,bmi,bmi2,sse4.2,popcnt,lzcnt")
*/

#include <bits/stdc++.h>
#define taskname ""
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define i64 long long
#define isz(x) (int)x.size()
using namespace std;

template<bool ALLOW_NON_PREFIX_QUERY, class T, class F, class I>
struct fenwick_tree{
    int n;
    vector<T> data;
    F TT;
    T T_id;
    I Tinv;
    fenwick_tree(F TT, T T_id, I Tinv): TT(TT), T_id(T_id), Tinv(Tinv){ }
    fenwick_tree &operator=(const fenwick_tree &fw){
        n = fw.n;
        data = fw.data;
    }
    // O(n)
    void build(int n){
        assert(n >= 0);
        this->n = n;
        data.assign(n, T_id);
    }
    // O(n)
    void build(int n, T x){
        assert(n >= 0);
        this->n = n;
        data.assign(n, x);
        for(auto i = 1; i <= n; ++ i) if(i + (i & -i) <= n) data[i + (i & -i) - 1] = TT(data[i + (i & -i) - 1], data[i - 1]);
    }
    // O(n)
    template<class U>
    void build(const vector<U> &a){
        n = (int)a.size();
        data.resize(n);
        copy(a.begin(), a.end(), data.begin());
        for(auto i = 1; i <= n; ++ i) if(i + (i & -i) <= n) data[i + (i & -i) - 1] = TT(data[i + (i & -i) - 1], data[i - 1]);
    }
    // O(log(n))
    void update(int p, T x){
        assert(0 <= p && p < n);
        for(++ p; p <= n; p += p & -p) data[p - 1] = TT(data[p - 1], x);
    }
    // O(log(n))
    void set(int p, T x){
        update(p, TT(x, Tinv(query(p))));
    }
    // O(log(n))
    T prefix(int r) const{
        assert(0 <= r && r <= n);
        T s = T_id;
        for(; r > 0; r -= r & -r) s = TT(s, data[r - 1]);
        return s;
    }
    // O(log(n))
    T query(int l, int r) const{
        static_assert(ALLOW_NON_PREFIX_QUERY);
        assert(0 <= l && l <= r && r <= n);
        if(l == r) return T_id;
        T sum_minus = T_id, sum_plus = T_id;
        for(; l < r; r -= r & -r) sum_plus = TT(sum_plus, data[r - 1]);
        for(; r < l; l -= l & -l) sum_minus = TT(sum_minus, data[l - 1]);
        return TT(sum_plus, Tinv(sum_minus));
    }
    // O(log(n))
    T query(int p) const{
        static_assert(ALLOW_NON_PREFIX_QUERY);
        return query(p, p + 1);
    }
    // O(log(n))
    T query_all() const{
        return prefix(n);
    }
    // pred(sum[0, r)) is T, T, ..., T, F, F, ..., F, returns max r with T
    // O(log(n))
    int max_pref(auto pred) const{
        assert(pred(T_id));
        int p = 0;
        T sum = T_id;
        for(auto i = __lg(n + 1); i >= 0; -- i) if(p + (1 << i) <= n && pred(TT(sum, data[p + (1 << i) - 1]))){
            sum = TT(sum, data[p + (1 << i) - 1]);
            p += 1 << i;
        }
        return p;
    }
    template<class output_stream>
    friend output_stream &operator<<(output_stream &out, const fenwick_tree &fw){
        out << "{";
        for(auto i = 0; i < fw.n; ++ i){
            out << fw.query(i);
            if(i != fw.n - 1) out << ", ";
        }
        return out << '}';
    }
};

template<class T, class F, class I>
auto make_fenwick_tree(F TT, T T_id, I Tinv){
    return fenwick_tree<true, T, F, I>(TT, T_id, Tinv);
}
template<class T>
auto make_fenwick_tree_sum(){
    return fenwick_tree<true, T, plus<>, negate<>>(plus<>(), T{0}, negate<>());
}
template<class T>
auto make_fenwick_tree_product(){
    auto inverse = [](const T &x){ return 1 / x; };
    return fenwick_tree<true, T, multiplies<>, decltype(inverse)>(multiplies<>(), T{1}, inverse);
}
template<class T>
auto make_fenwick_tree_min(){
    auto TT = [&](const T &x, const T &y)->T{ return min(x, y); };
    return fenwick_tree<false, T, decltype(TT), negate<>>(TT, numeric_limits<T>::max(), negate<>());
}
template<class T>
auto make_fenwick_tree_max(){
    auto TT = [&](const T &x, const T &y)->T{ return max(x, y); };
    return fenwick_tree<false, T, decltype(TT), negate<>>(TT, numeric_limits<T>::max(), negate<>());
}

template<class T>
struct graph{
    using Weight_t = T;
    struct Edge_t{
        int from, to;
        T cost;
    };
    int n;
    vector<Edge_t> edge;
    vector<vector<int>> adj;
    function<bool(int)> ignore;
    graph(int n = 1): n(n), adj(n){
        assert(n >= 1);
    }
    graph(const vector<vector<int>> &adj, bool undirected = true): n((int)adj.size()), adj(n){
        assert(n >= 1);
        if(undirected){
            for(auto u = 0; u < n; ++ u) for(auto v: adj[u]) if(u < v) link(u, v);
        }
        else for(auto u = 0; u < n; ++ u) for(auto v: adj[u]) orient(u, v);
    }
    graph(const vector<vector<pair<int, T>>> &adj, bool undirected = true): n((int)adj.size()), adj(n){
        assert(n >= 1);
        if(undirected){
            for(auto u = 0; u < n; ++ u) for(auto [v, w]: adj[u]) if(u < v) link(u, v, w);
        }
        else for(auto u = 0; u < n; ++ u) for(auto [v, w]: adj[u]) orient(u, v, w);
    }
    graph(int n, vector<array<int, 2>> &edge, bool undirected = true): n(n), adj(n){
        assert(n >= 1);
        for(auto [u, v]: edge) undirected ? link(u, v) : orient(u, v);
    }
    graph(int n, vector<tuple<int, int, T>> &edge, bool undirected = true): n(n), adj(n){
        assert(n >= 1);
        for(auto [u, v, w]: edge) undirected ? link(u, v, w) : orient(u, v, w);
    }
    int add_vertex(){
        adj.emplace_back();
        return n ++;
    }
    int operator()(int u, int id) const{
        #ifdef LOCAL
        assert(0 <= id && id < (int)edge.size());
        assert(edge[id].from == u || edge[id].to == u);
        #endif
        return u ^ edge[id].from ^ edge[id].to;
    }
    int link(int u, int v, T w = {}){ // insert an undirected edge
        int id = (int)edge.size();
        adj[u].push_back(id), adj[v].push_back(id), edge.push_back({u, v, w});
        return id;
    }
    int orient(int u, int v, T w = {}){ // insert a directed edge
        int id = (int)edge.size();
        adj[u].push_back(id), edge.push_back({u, v, w});
        return id;
    }
    vector<int> neighbor(int u, int exclude = -1) const{
        vector<int> res;
        for(auto id: adj[u]){
            if(id == exclude || ignore && ignore(id)) continue;
            res.push_back(operator()(u, id));
        }
        return res;
    }
    void clear(){
        for(auto [u, v, w]: edge){
            adj[u].clear();
            adj[v].clear();
        }
        edge.clear();
        ignore = {};
    }
    graph transpose() const{ // the transpose of the directed graph
        graph res(n);
        for(auto id = 0; id < (int)edge.size(); ++ id){
            if(ignore && ignore(id)) continue;
            res.orient(edge[id].to, edge[id].from, edge[id].cost);
        }
        return res;
    }
    int degree(int u) const{ // the degree (outdegree if directed) of u (without the ignoration rule)
        return (int)adj[u].size();
    }
    // The adjacency list is sorted for each vertex.
    vector<vector<int>> get_adjacency_list() const{
        vector<vector<int>> res(n);
        for(auto u = 0; u < n; ++ u) for(auto id: adj[u]){
            if(ignore && ignore(id)) continue;
            res[(*this)(u, id)].push_back(u);
        }
        return res;
    }
    void set_ignoration_rule(const function<bool(int)> &f){
        ignore = f;
    }
    void reset_ignoration_rule(){
        ignore = nullptr;
    }
    friend ostream &operator<<(ostream &out, const graph &g){
        for(auto id = 0; id < (int)g.edge.size(); ++ id){
            if(g.ignore && g.ignore(id)) continue;
            auto &e = g.edge[id];
            out << "{" << e.from << ", " << e.to << ", " << e.cost << "}\n";
        }
        return out;
    }
};

struct Query {
    int v, qid;
    Query(int v, int qid) : v(v), qid(qid) {}
};

void solve() {
    int n, q;
    cin >> n >> q;

    graph<int> g(n);
    vector<int> tpq(n + q), res(n + q);
    vector<vector<Query>> queries(n);
    for (int i = 0; i < n - 1 + q; ++i) {
        char ch;
        cin >> ch;
        if (ch == 'S') {
            int u, v;
            cin >> u >> v;
            --u, --v;
            g.link(u, v, i);
            tpq[i] = 0;
        }
        else if (ch == 'Q') {
            int u, v;
            cin >> u >> v;
            --u, --v;
            queries[v].emplace_back(u, i);
            tpq[i] = 1;
        }
        else {
            int u;
            cin >> u;
            --u;
            queries[u].emplace_back(-1, i);
            tpq[i] = 2;
        }
    }

    for (int i = 0; i < n; ++i) {
        reverse(all(g.adj[i]));
    }

    int tot_sz = 0;
    vector<bool> vis(n);
    vector<int> sz(n);

    auto get_sz = [&](auto self, int u, int _pid) -> void {
        sz[u] = 1;
        for (auto id : g.adj[u]) if (id != _pid and not vis[g(u, id)]) {
            int v = g(u, id);
            self(self, v, id);
            sz[u] += sz[v];
        }
    };

    auto find_cen = [&](auto self, int u, int _pid) -> int {
        for (auto id : g.adj[u]) if (id != _pid and not vis[g(u, id)]) {
            int v = g(u, id);
            if (sz[v] > (tot_sz >> 1)) {
                return self(self, v, id);
            }
        }
        return u;
    };

    auto get_cen = [&](int v) -> int {
        get_sz(get_sz, v, -1);
        tot_sz = sz[v];
        return find_cen(find_cen, v, -1);
    };

    auto fenw = make_fenwick_tree_sum<int>();
    fenw.build(n + q);

    vector<int> vis_dfs(n, n + q);
    vector<pair<int, int>> rst;
    auto dfs1 = [&](auto self, int u, int _pid, int pw) -> void {
        for (auto [v, qid] : queries[u]) {
            if (v == -1) {
                res[qid] += fenw.prefix(qid);
            }
            else {
                res[qid] |= (vis_dfs[v] <= qid);
            }
        }
        for (auto id : g.adj[u]) if (id != _pid and not vis[g(u, id)] and g.edge[id].cost < pw) {
            int v = g(u, id);
            self(self, v, id, g.edge[id].cost);
        }
    };

    auto add = [&](int u, int pw) -> void {
        vis_dfs[u] = pw;
        fenw.update(pw, 1);
        rst.emplace_back(u, pw);
    };

    auto dfs2 = [&](auto self, int u, int _pid, int pw) -> void {
        add(u, pw);
        for (auto id : g.adj[u]) if (id != _pid and not vis[g(u, id)] and g.edge[id].cost > pw) {
            int v = g(u, id);
            self(self, v, id, g.edge[id].cost);
        }
    };

    auto reset = [&]() -> void {
        while (not rst.empty()) {
            auto [u, pw] = rst.back();
            rst.pop_back();
            vis_dfs[u] = n + q;
            fenw.update(pw, -1);
        }
    };

    auto centroid = [&](auto self, int u) -> void {
        vis[u] = true;
        for (auto id : g.adj[u]) if (not vis[g(u, id)]) {
            int v = g(u, id);
            add(u, g.edge[id].cost);
            dfs1(dfs1, v, -1, g.edge[id].cost);
            {
                auto [u, pw] = rst.back();
                rst.pop_back();
                vis_dfs[u] = n + q;
                fenw.update(pw, -1);
            }
            dfs2(dfs2, v, -1, g.edge[id].cost);
        }
        add(u, 0);
        for (auto [v, qid] : queries[u]) {
            if (v == -1) {
                res[qid] += fenw.prefix(qid);
            }
            else {
                res[qid] |= (vis_dfs[v] <= qid);
            }
        }
        reset();

        for (auto id : g.adj[u]) if (not vis[g(u, id)]) {
            int v = g(u, id);
            int nxt_cen = get_cen(v);
            self(self, nxt_cen);
        }
    };

    int cen = get_cen(0);
    centroid(centroid, cen);

    vector<int> vc;
    for (int i = 0; i < n + q - 1; ++i) {
        if (tpq[i] == 1) {
            vc.emplace_back(res[i] ? -1 : -2);
        }
        else if (tpq[i] == 2) {
            vc.emplace_back(res[i]);
        }
    }

    vc.resize(q);
    for (auto val : vc) {
        if (val == -1) {
            cout << "yes\n";
        }
        else if (val == -2) {
            cout << "no\n";
        }
        else {
            cout << val << "\n";
        }
    }
}

signed main() {

#ifndef CDuongg
    if (fopen(taskname".inp", "r"))
        assert(freopen(taskname".inp", "r", stdin)), assert(freopen(taskname".out", "w", stdout));
#else
    freopen("bai3.inp", "r", stdin);
    freopen("bai3.out", "w", stdout);
    auto start = chrono::high_resolution_clock::now();
#endif

    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    int t = 1; //cin >> t;
    while(t--) solve();

#ifdef CDuongg
   auto end = chrono::high_resolution_clock::now();
   cout << "\n"; for(int i = 1; i <= 100; ++i) cout << '=';
   cout << "\nExecution time: " << chrono::duration_cast<chrono::milliseconds> (end - start).count() << "[ms]" << endl;
#endif

}

Compilation message

servers.cpp:84:18: warning: use of 'auto' in parameter declaration only available with '-fconcepts-ts'
   84 |     int max_pref(auto pred) const{
      |                  ^~~~
# 결과 실행 시간 메모리 Grader output
1 Correct 15 ms 5076 KB Output is correct
2 Correct 23 ms 6244 KB Output is correct
3 Correct 21 ms 6108 KB Output is correct
4 Correct 23 ms 6348 KB Output is correct
5 Correct 23 ms 6356 KB Output is correct
6 Correct 22 ms 6352 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 15 ms 5076 KB Output is correct
2 Correct 23 ms 6244 KB Output is correct
3 Correct 21 ms 6108 KB Output is correct
4 Correct 23 ms 6348 KB Output is correct
5 Correct 23 ms 6356 KB Output is correct
6 Correct 22 ms 6352 KB Output is correct
7 Correct 15 ms 5076 KB Output is correct
8 Incorrect 26 ms 5836 KB Extra information in the output file
9 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 14 ms 5072 KB Output is correct
2 Correct 84 ms 22944 KB Output is correct
3 Correct 87 ms 22904 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 14 ms 5072 KB Output is correct
2 Correct 84 ms 22944 KB Output is correct
3 Correct 87 ms 22904 KB Output is correct
4 Correct 18 ms 5072 KB Output is correct
5 Correct 92 ms 22656 KB Output is correct
6 Correct 65 ms 20684 KB Output is correct
7 Correct 72 ms 20880 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 17 ms 5076 KB Output is correct
2 Correct 211 ms 28332 KB Output is correct
3 Correct 202 ms 28424 KB Output is correct
4 Correct 173 ms 28932 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 17 ms 5076 KB Output is correct
2 Correct 211 ms 28332 KB Output is correct
3 Correct 202 ms 28424 KB Output is correct
4 Correct 173 ms 28932 KB Output is correct
5 Correct 20 ms 5072 KB Output is correct
6 Correct 224 ms 27912 KB Output is correct
7 Correct 183 ms 28760 KB Output is correct
8 Correct 206 ms 27616 KB Output is correct
9 Correct 221 ms 27656 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 15 ms 5076 KB Output is correct
2 Correct 163 ms 22536 KB Output is correct
3 Correct 146 ms 22020 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 15 ms 5076 KB Output is correct
2 Correct 163 ms 22536 KB Output is correct
3 Correct 146 ms 22020 KB Output is correct
4 Correct 22 ms 5068 KB Output is correct
5 Correct 165 ms 22276 KB Output is correct
6 Correct 149 ms 21768 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 15 ms 5088 KB Output is correct
2 Correct 216 ms 28404 KB Output is correct
3 Correct 204 ms 28420 KB Output is correct
4 Correct 179 ms 28936 KB Output is correct
5 Correct 15 ms 5076 KB Output is correct
6 Correct 144 ms 22496 KB Output is correct
7 Correct 147 ms 21884 KB Output is correct
8 Correct 144 ms 22536 KB Output is correct
9 Correct 152 ms 22520 KB Output is correct
10 Correct 265 ms 25604 KB Output is correct
11 Correct 244 ms 25860 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 15 ms 5088 KB Output is correct
2 Correct 216 ms 28404 KB Output is correct
3 Correct 204 ms 28420 KB Output is correct
4 Correct 179 ms 28936 KB Output is correct
5 Correct 15 ms 5076 KB Output is correct
6 Correct 144 ms 22496 KB Output is correct
7 Correct 147 ms 21884 KB Output is correct
8 Correct 144 ms 22536 KB Output is correct
9 Correct 152 ms 22520 KB Output is correct
10 Correct 265 ms 25604 KB Output is correct
11 Correct 244 ms 25860 KB Output is correct
12 Correct 20 ms 5068 KB Output is correct
13 Correct 212 ms 28040 KB Output is correct
14 Correct 191 ms 28676 KB Output is correct
15 Correct 222 ms 27652 KB Output is correct
16 Correct 210 ms 27652 KB Output is correct
17 Correct 16 ms 4948 KB Output is correct
18 Correct 179 ms 22280 KB Output is correct
19 Correct 149 ms 21764 KB Output is correct
20 Correct 154 ms 22280 KB Output is correct
21 Correct 161 ms 22292 KB Output is correct
22 Correct 265 ms 24836 KB Output is correct
23 Correct 263 ms 25352 KB Output is correct
24 Correct 266 ms 25352 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 15 ms 5072 KB Output is correct
2 Correct 22 ms 6140 KB Output is correct
3 Correct 21 ms 6108 KB Output is correct
4 Correct 24 ms 6204 KB Output is correct
5 Correct 23 ms 6364 KB Output is correct
6 Correct 22 ms 6608 KB Output is correct
7 Correct 14 ms 5076 KB Output is correct
8 Correct 95 ms 22968 KB Output is correct
9 Correct 96 ms 22908 KB Output is correct
10 Correct 15 ms 4920 KB Output is correct
11 Correct 200 ms 28284 KB Output is correct
12 Correct 200 ms 28428 KB Output is correct
13 Correct 156 ms 28784 KB Output is correct
14 Correct 15 ms 5072 KB Output is correct
15 Correct 146 ms 22596 KB Output is correct
16 Correct 155 ms 21844 KB Output is correct
17 Correct 144 ms 22536 KB Output is correct
18 Correct 159 ms 22280 KB Output is correct
19 Correct 236 ms 25632 KB Output is correct
20 Correct 249 ms 25612 KB Output is correct
21 Correct 106 ms 23304 KB Output is correct
22 Correct 103 ms 23044 KB Output is correct
23 Correct 133 ms 22520 KB Output is correct
24 Correct 131 ms 22584 KB Output is correct
25 Correct 196 ms 25860 KB Output is correct
26 Correct 149 ms 21668 KB Output is correct
27 Correct 141 ms 21512 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 15 ms 5072 KB Output is correct
2 Correct 22 ms 6140 KB Output is correct
3 Correct 21 ms 6108 KB Output is correct
4 Correct 24 ms 6204 KB Output is correct
5 Correct 23 ms 6364 KB Output is correct
6 Correct 22 ms 6608 KB Output is correct
7 Correct 14 ms 5076 KB Output is correct
8 Correct 95 ms 22968 KB Output is correct
9 Correct 96 ms 22908 KB Output is correct
10 Correct 15 ms 4920 KB Output is correct
11 Correct 200 ms 28284 KB Output is correct
12 Correct 200 ms 28428 KB Output is correct
13 Correct 156 ms 28784 KB Output is correct
14 Correct 15 ms 5072 KB Output is correct
15 Correct 146 ms 22596 KB Output is correct
16 Correct 155 ms 21844 KB Output is correct
17 Correct 144 ms 22536 KB Output is correct
18 Correct 159 ms 22280 KB Output is correct
19 Correct 236 ms 25632 KB Output is correct
20 Correct 249 ms 25612 KB Output is correct
21 Correct 106 ms 23304 KB Output is correct
22 Correct 103 ms 23044 KB Output is correct
23 Correct 133 ms 22520 KB Output is correct
24 Correct 131 ms 22584 KB Output is correct
25 Correct 196 ms 25860 KB Output is correct
26 Correct 149 ms 21668 KB Output is correct
27 Correct 141 ms 21512 KB Output is correct
28 Correct 18 ms 5064 KB Output is correct
29 Incorrect 27 ms 5832 KB Extra information in the output file
30 Halted 0 ms 0 KB -