Submission #1093622

# Submission time Handle Problem Language Result Execution time Memory
1093622 2024-09-27T06:56:48 Z CDuong Inside information (BOI21_servers) C++17
80 / 100
307 ms 28868 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 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{
      |                  ^~~~
# Verdict Execution time Memory Grader output
1 Correct 14 ms 5076 KB Output is correct
2 Correct 26 ms 6124 KB Output is correct
3 Correct 27 ms 6044 KB Output is correct
4 Correct 23 ms 6152 KB Output is correct
5 Correct 24 ms 6364 KB Output is correct
6 Correct 22 ms 6260 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 14 ms 5076 KB Output is correct
2 Correct 26 ms 6124 KB Output is correct
3 Correct 27 ms 6044 KB Output is correct
4 Correct 23 ms 6152 KB Output is correct
5 Correct 24 ms 6364 KB Output is correct
6 Correct 22 ms 6260 KB Output is correct
7 Correct 27 ms 5068 KB Output is correct
8 Incorrect 30 ms 5832 KB Extra information in the output file
9 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 14 ms 5076 KB Output is correct
2 Correct 121 ms 22912 KB Output is correct
3 Correct 92 ms 22844 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 14 ms 5076 KB Output is correct
2 Correct 121 ms 22912 KB Output is correct
3 Correct 92 ms 22844 KB Output is correct
4 Correct 15 ms 5100 KB Output is correct
5 Correct 92 ms 22536 KB Output is correct
6 Correct 65 ms 20644 KB Output is correct
7 Correct 76 ms 20868 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 15 ms 5072 KB Output is correct
2 Correct 206 ms 28424 KB Output is correct
3 Correct 192 ms 28676 KB Output is correct
4 Correct 161 ms 28868 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 15 ms 5072 KB Output is correct
2 Correct 206 ms 28424 KB Output is correct
3 Correct 192 ms 28676 KB Output is correct
4 Correct 161 ms 28868 KB Output is correct
5 Correct 15 ms 5076 KB Output is correct
6 Correct 199 ms 27912 KB Output is correct
7 Correct 171 ms 28676 KB Output is correct
8 Correct 198 ms 27656 KB Output is correct
9 Correct 192 ms 27656 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 14 ms 5072 KB Output is correct
2 Correct 152 ms 22536 KB Output is correct
3 Correct 139 ms 21924 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 14 ms 5072 KB Output is correct
2 Correct 152 ms 22536 KB Output is correct
3 Correct 139 ms 21924 KB Output is correct
4 Correct 15 ms 5076 KB Output is correct
5 Correct 156 ms 22296 KB Output is correct
6 Correct 161 ms 21728 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 15 ms 5176 KB Output is correct
2 Correct 205 ms 28420 KB Output is correct
3 Correct 213 ms 28296 KB Output is correct
4 Correct 161 ms 28828 KB Output is correct
5 Correct 15 ms 5064 KB Output is correct
6 Correct 148 ms 22536 KB Output is correct
7 Correct 158 ms 21768 KB Output is correct
8 Correct 152 ms 22552 KB Output is correct
9 Correct 150 ms 22280 KB Output is correct
10 Correct 286 ms 25456 KB Output is correct
11 Correct 271 ms 25528 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 15 ms 5176 KB Output is correct
2 Correct 205 ms 28420 KB Output is correct
3 Correct 213 ms 28296 KB Output is correct
4 Correct 161 ms 28828 KB Output is correct
5 Correct 15 ms 5064 KB Output is correct
6 Correct 148 ms 22536 KB Output is correct
7 Correct 158 ms 21768 KB Output is correct
8 Correct 152 ms 22552 KB Output is correct
9 Correct 150 ms 22280 KB Output is correct
10 Correct 286 ms 25456 KB Output is correct
11 Correct 271 ms 25528 KB Output is correct
12 Correct 15 ms 5076 KB Output is correct
13 Correct 220 ms 28060 KB Output is correct
14 Correct 177 ms 28680 KB Output is correct
15 Correct 224 ms 27504 KB Output is correct
16 Correct 229 ms 27536 KB Output is correct
17 Correct 15 ms 5076 KB Output is correct
18 Correct 168 ms 22352 KB Output is correct
19 Correct 170 ms 21704 KB Output is correct
20 Correct 178 ms 22276 KB Output is correct
21 Correct 157 ms 22228 KB Output is correct
22 Correct 277 ms 24964 KB Output is correct
23 Correct 299 ms 25224 KB Output is correct
24 Correct 307 ms 25328 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 17 ms 5076 KB Output is correct
2 Correct 29 ms 6148 KB Output is correct
3 Correct 25 ms 6108 KB Output is correct
4 Correct 26 ms 6220 KB Output is correct
5 Correct 26 ms 6552 KB Output is correct
6 Correct 25 ms 6220 KB Output is correct
7 Correct 24 ms 5076 KB Output is correct
8 Correct 123 ms 22792 KB Output is correct
9 Correct 165 ms 22912 KB Output is correct
10 Correct 15 ms 5024 KB Output is correct
11 Correct 240 ms 28284 KB Output is correct
12 Correct 243 ms 28288 KB Output is correct
13 Correct 176 ms 28772 KB Output is correct
14 Correct 16 ms 5076 KB Output is correct
15 Correct 158 ms 22480 KB Output is correct
16 Correct 145 ms 21848 KB Output is correct
17 Correct 177 ms 22564 KB Output is correct
18 Correct 142 ms 22536 KB Output is correct
19 Correct 231 ms 25536 KB Output is correct
20 Correct 227 ms 25608 KB Output is correct
21 Correct 100 ms 23300 KB Output is correct
22 Correct 103 ms 22940 KB Output is correct
23 Correct 124 ms 22536 KB Output is correct
24 Correct 130 ms 22604 KB Output is correct
25 Correct 179 ms 25724 KB Output is correct
26 Correct 156 ms 21672 KB Output is correct
27 Correct 138 ms 21468 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 17 ms 5076 KB Output is correct
2 Correct 29 ms 6148 KB Output is correct
3 Correct 25 ms 6108 KB Output is correct
4 Correct 26 ms 6220 KB Output is correct
5 Correct 26 ms 6552 KB Output is correct
6 Correct 25 ms 6220 KB Output is correct
7 Correct 24 ms 5076 KB Output is correct
8 Correct 123 ms 22792 KB Output is correct
9 Correct 165 ms 22912 KB Output is correct
10 Correct 15 ms 5024 KB Output is correct
11 Correct 240 ms 28284 KB Output is correct
12 Correct 243 ms 28288 KB Output is correct
13 Correct 176 ms 28772 KB Output is correct
14 Correct 16 ms 5076 KB Output is correct
15 Correct 158 ms 22480 KB Output is correct
16 Correct 145 ms 21848 KB Output is correct
17 Correct 177 ms 22564 KB Output is correct
18 Correct 142 ms 22536 KB Output is correct
19 Correct 231 ms 25536 KB Output is correct
20 Correct 227 ms 25608 KB Output is correct
21 Correct 100 ms 23300 KB Output is correct
22 Correct 103 ms 22940 KB Output is correct
23 Correct 124 ms 22536 KB Output is correct
24 Correct 130 ms 22604 KB Output is correct
25 Correct 179 ms 25724 KB Output is correct
26 Correct 156 ms 21672 KB Output is correct
27 Correct 138 ms 21468 KB Output is correct
28 Correct 16 ms 5076 KB Output is correct
29 Incorrect 26 ms 5840 KB Extra information in the output file
30 Halted 0 ms 0 KB -