답안 #1093624

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1093624 2024-09-27T06:57:47 Z CDuong Inside information (BOI21_servers) C++17
80 / 100
265 ms 27552 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);
    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), res(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 del = [&]() -> void {
        auto [u, pw] = rst.back();
        rst.pop_back();
        vis_dfs[u] = n + q;
        fenw.update(pw, -1);
    };

    auto reset = [&]() -> void {
        while (not rst.empty()) {
            del();
        }
    };

    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);
            del();
            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 4820 KB Output is correct
2 Correct 27 ms 5976 KB Output is correct
3 Correct 23 ms 5588 KB Output is correct
4 Correct 25 ms 5836 KB Output is correct
5 Correct 24 ms 6108 KB Output is correct
6 Correct 23 ms 5876 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 15 ms 4820 KB Output is correct
2 Correct 27 ms 5976 KB Output is correct
3 Correct 23 ms 5588 KB Output is correct
4 Correct 25 ms 5836 KB Output is correct
5 Correct 24 ms 6108 KB Output is correct
6 Correct 23 ms 5876 KB Output is correct
7 Correct 15 ms 4772 KB Output is correct
8 Incorrect 28 ms 5580 KB Extra information in the output file
9 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 15 ms 5076 KB Output is correct
2 Correct 96 ms 22088 KB Output is correct
3 Correct 86 ms 21888 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 15 ms 5076 KB Output is correct
2 Correct 96 ms 22088 KB Output is correct
3 Correct 86 ms 21888 KB Output is correct
4 Correct 15 ms 4820 KB Output is correct
5 Correct 89 ms 21432 KB Output is correct
6 Correct 67 ms 19956 KB Output is correct
7 Correct 65 ms 20048 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 14 ms 4816 KB Output is correct
2 Correct 190 ms 26812 KB Output is correct
3 Correct 199 ms 26700 KB Output is correct
4 Correct 158 ms 27472 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 14 ms 4816 KB Output is correct
2 Correct 190 ms 26812 KB Output is correct
3 Correct 199 ms 26700 KB Output is correct
4 Correct 158 ms 27472 KB Output is correct
5 Correct 15 ms 4820 KB Output is correct
6 Correct 200 ms 26884 KB Output is correct
7 Correct 171 ms 27400 KB Output is correct
8 Correct 193 ms 26608 KB Output is correct
9 Correct 204 ms 26376 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 16 ms 4808 KB Output is correct
2 Correct 148 ms 21072 KB Output is correct
3 Correct 146 ms 20484 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 16 ms 4808 KB Output is correct
2 Correct 148 ms 21072 KB Output is correct
3 Correct 146 ms 20484 KB Output is correct
4 Correct 15 ms 4816 KB Output is correct
5 Correct 167 ms 21168 KB Output is correct
6 Correct 148 ms 20576 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 14 ms 4980 KB Output is correct
2 Correct 205 ms 26880 KB Output is correct
3 Correct 196 ms 26888 KB Output is correct
4 Correct 160 ms 27308 KB Output is correct
5 Correct 15 ms 4816 KB Output is correct
6 Correct 160 ms 21000 KB Output is correct
7 Correct 172 ms 20484 KB Output is correct
8 Correct 142 ms 20996 KB Output is correct
9 Correct 150 ms 21000 KB Output is correct
10 Correct 239 ms 24284 KB Output is correct
11 Correct 227 ms 24088 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 14 ms 4980 KB Output is correct
2 Correct 205 ms 26880 KB Output is correct
3 Correct 196 ms 26888 KB Output is correct
4 Correct 160 ms 27308 KB Output is correct
5 Correct 15 ms 4816 KB Output is correct
6 Correct 160 ms 21000 KB Output is correct
7 Correct 172 ms 20484 KB Output is correct
8 Correct 142 ms 20996 KB Output is correct
9 Correct 150 ms 21000 KB Output is correct
10 Correct 239 ms 24284 KB Output is correct
11 Correct 227 ms 24088 KB Output is correct
12 Correct 15 ms 4816 KB Output is correct
13 Correct 199 ms 26824 KB Output is correct
14 Correct 178 ms 27552 KB Output is correct
15 Correct 199 ms 26568 KB Output is correct
16 Correct 193 ms 26392 KB Output is correct
17 Correct 15 ms 4816 KB Output is correct
18 Correct 161 ms 21016 KB Output is correct
19 Correct 154 ms 20904 KB Output is correct
20 Correct 142 ms 21000 KB Output is correct
21 Correct 149 ms 20996 KB Output is correct
22 Correct 262 ms 23704 KB Output is correct
23 Correct 255 ms 24064 KB Output is correct
24 Correct 265 ms 23880 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 15 ms 4816 KB Output is correct
2 Correct 24 ms 5836 KB Output is correct
3 Correct 26 ms 5592 KB Output is correct
4 Correct 25 ms 5848 KB Output is correct
5 Correct 25 ms 5996 KB Output is correct
6 Correct 22 ms 5836 KB Output is correct
7 Correct 15 ms 5076 KB Output is correct
8 Correct 93 ms 21796 KB Output is correct
9 Correct 89 ms 21884 KB Output is correct
10 Correct 15 ms 5052 KB Output is correct
11 Correct 247 ms 26756 KB Output is correct
12 Correct 191 ms 26680 KB Output is correct
13 Correct 154 ms 27388 KB Output is correct
14 Correct 21 ms 4864 KB Output is correct
15 Correct 142 ms 20944 KB Output is correct
16 Correct 138 ms 20368 KB Output is correct
17 Correct 141 ms 20996 KB Output is correct
18 Correct 147 ms 20840 KB Output is correct
19 Correct 232 ms 24304 KB Output is correct
20 Correct 225 ms 24132 KB Output is correct
21 Correct 106 ms 21980 KB Output is correct
22 Correct 104 ms 21508 KB Output is correct
23 Correct 133 ms 21032 KB Output is correct
24 Correct 141 ms 21008 KB Output is correct
25 Correct 231 ms 24328 KB Output is correct
26 Correct 153 ms 20308 KB Output is correct
27 Correct 144 ms 20228 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 15 ms 4816 KB Output is correct
2 Correct 24 ms 5836 KB Output is correct
3 Correct 26 ms 5592 KB Output is correct
4 Correct 25 ms 5848 KB Output is correct
5 Correct 25 ms 5996 KB Output is correct
6 Correct 22 ms 5836 KB Output is correct
7 Correct 15 ms 5076 KB Output is correct
8 Correct 93 ms 21796 KB Output is correct
9 Correct 89 ms 21884 KB Output is correct
10 Correct 15 ms 5052 KB Output is correct
11 Correct 247 ms 26756 KB Output is correct
12 Correct 191 ms 26680 KB Output is correct
13 Correct 154 ms 27388 KB Output is correct
14 Correct 21 ms 4864 KB Output is correct
15 Correct 142 ms 20944 KB Output is correct
16 Correct 138 ms 20368 KB Output is correct
17 Correct 141 ms 20996 KB Output is correct
18 Correct 147 ms 20840 KB Output is correct
19 Correct 232 ms 24304 KB Output is correct
20 Correct 225 ms 24132 KB Output is correct
21 Correct 106 ms 21980 KB Output is correct
22 Correct 104 ms 21508 KB Output is correct
23 Correct 133 ms 21032 KB Output is correct
24 Correct 141 ms 21008 KB Output is correct
25 Correct 231 ms 24328 KB Output is correct
26 Correct 153 ms 20308 KB Output is correct
27 Correct 144 ms 20228 KB Output is correct
28 Correct 15 ms 4808 KB Output is correct
29 Incorrect 27 ms 5588 KB Extra information in the output file
30 Halted 0 ms 0 KB -