Submission #1093616

# Submission time Handle Problem Language Result Execution time Memory
1093616 2024-09-27T06:49:51 Z CDuong Inside information (BOI21_servers) C++17
80 / 100
253 ms 25516 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, val, qid;
    Query(int v, int val, int qid) : v(v), val(val), 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, i);
            tpq[i] = 1;
        }
        else {
            int u;
            cin >> u;
            --u;
            queries[u].emplace_back(-1, i, 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, val, qid] : queries[u]) {
            if (v == -1) {
                res[qid] += fenw.prefix(val);
            }
            else {
                res[qid] |= (vis_dfs[v] <= val);
            }
        }
        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, val, qid] : queries[u]) {
            if (v == -1) {
                res[qid] += fenw.prefix(val);
            }
            else {
                res[qid] |= (vis_dfs[v] <= val);
            }
        }
        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);

    int cntq = 0;
    for (int i = 0; i < n + q - 1; ++i) {
        if (tpq[i] == 1) {
            cout << (res[i] ? "yes" : "no");
        }
        else if (tpq[i] == 2)   {
            cout << res[i];
        }
        if (tpq[i] and ++cntq < q) {
            cout << "\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 16 ms 4444 KB Output is correct
2 Correct 25 ms 4952 KB Output is correct
3 Correct 32 ms 4700 KB Output is correct
4 Correct 24 ms 5068 KB Output is correct
5 Correct 25 ms 5328 KB Output is correct
6 Correct 24 ms 4956 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 16 ms 4444 KB Output is correct
2 Correct 25 ms 4952 KB Output is correct
3 Correct 32 ms 4700 KB Output is correct
4 Correct 24 ms 5068 KB Output is correct
5 Correct 25 ms 5328 KB Output is correct
6 Correct 24 ms 4956 KB Output is correct
7 Correct 20 ms 4188 KB Output is correct
8 Incorrect 37 ms 5056 KB Extra information in the output file
9 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 17 ms 4444 KB Output is correct
2 Correct 104 ms 20352 KB Output is correct
3 Correct 115 ms 20352 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 17 ms 4444 KB Output is correct
2 Correct 104 ms 20352 KB Output is correct
3 Correct 115 ms 20352 KB Output is correct
4 Correct 16 ms 4188 KB Output is correct
5 Correct 112 ms 20188 KB Output is correct
6 Correct 65 ms 19504 KB Output is correct
7 Correct 72 ms 19268 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 17 ms 4532 KB Output is correct
2 Correct 221 ms 24364 KB Output is correct
3 Correct 210 ms 24264 KB Output is correct
4 Correct 179 ms 25348 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 17 ms 4532 KB Output is correct
2 Correct 221 ms 24364 KB Output is correct
3 Correct 210 ms 24264 KB Output is correct
4 Correct 179 ms 25348 KB Output is correct
5 Correct 21 ms 4184 KB Output is correct
6 Correct 243 ms 24264 KB Output is correct
7 Correct 192 ms 25320 KB Output is correct
8 Correct 228 ms 24068 KB Output is correct
9 Correct 230 ms 24084 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 17 ms 4444 KB Output is correct
2 Correct 177 ms 19052 KB Output is correct
3 Correct 182 ms 17928 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 17 ms 4444 KB Output is correct
2 Correct 177 ms 19052 KB Output is correct
3 Correct 182 ms 17928 KB Output is correct
4 Correct 17 ms 4324 KB Output is correct
5 Correct 175 ms 18920 KB Output is correct
6 Correct 181 ms 17928 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 16 ms 4444 KB Output is correct
2 Correct 229 ms 24164 KB Output is correct
3 Correct 236 ms 24124 KB Output is correct
4 Correct 180 ms 25352 KB Output is correct
5 Correct 16 ms 4444 KB Output is correct
6 Correct 156 ms 19048 KB Output is correct
7 Correct 153 ms 17924 KB Output is correct
8 Correct 172 ms 18576 KB Output is correct
9 Correct 168 ms 18376 KB Output is correct
10 Correct 253 ms 21512 KB Output is correct
11 Correct 243 ms 21560 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 16 ms 4444 KB Output is correct
2 Correct 229 ms 24164 KB Output is correct
3 Correct 236 ms 24124 KB Output is correct
4 Correct 180 ms 25352 KB Output is correct
5 Correct 16 ms 4444 KB Output is correct
6 Correct 156 ms 19048 KB Output is correct
7 Correct 153 ms 17924 KB Output is correct
8 Correct 172 ms 18576 KB Output is correct
9 Correct 168 ms 18376 KB Output is correct
10 Correct 253 ms 21512 KB Output is correct
11 Correct 243 ms 21560 KB Output is correct
12 Correct 17 ms 4360 KB Output is correct
13 Correct 216 ms 24228 KB Output is correct
14 Correct 190 ms 25516 KB Output is correct
15 Correct 196 ms 24068 KB Output is correct
16 Correct 232 ms 24072 KB Output is correct
17 Correct 16 ms 4184 KB Output is correct
18 Correct 171 ms 18948 KB Output is correct
19 Correct 143 ms 17928 KB Output is correct
20 Correct 153 ms 18440 KB Output is correct
21 Correct 151 ms 18440 KB Output is correct
22 Correct 230 ms 21524 KB Output is correct
23 Correct 239 ms 21768 KB Output is correct
24 Correct 232 ms 22020 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 25 ms 4444 KB Output is correct
2 Correct 27 ms 5076 KB Output is correct
3 Correct 29 ms 4748 KB Output is correct
4 Correct 25 ms 4956 KB Output is correct
5 Correct 24 ms 5272 KB Output is correct
6 Correct 22 ms 4956 KB Output is correct
7 Correct 15 ms 4440 KB Output is correct
8 Correct 86 ms 20352 KB Output is correct
9 Correct 82 ms 20388 KB Output is correct
10 Correct 16 ms 4440 KB Output is correct
11 Correct 191 ms 24324 KB Output is correct
12 Correct 194 ms 24324 KB Output is correct
13 Correct 165 ms 25464 KB Output is correct
14 Correct 15 ms 4460 KB Output is correct
15 Correct 142 ms 18924 KB Output is correct
16 Correct 143 ms 17924 KB Output is correct
17 Correct 144 ms 18440 KB Output is correct
18 Correct 137 ms 18532 KB Output is correct
19 Correct 226 ms 21516 KB Output is correct
20 Correct 234 ms 21508 KB Output is correct
21 Correct 96 ms 20056 KB Output is correct
22 Correct 102 ms 19464 KB Output is correct
23 Correct 130 ms 18692 KB Output is correct
24 Correct 136 ms 18708 KB Output is correct
25 Correct 190 ms 22280 KB Output is correct
26 Correct 146 ms 17668 KB Output is correct
27 Correct 154 ms 17928 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 25 ms 4444 KB Output is correct
2 Correct 27 ms 5076 KB Output is correct
3 Correct 29 ms 4748 KB Output is correct
4 Correct 25 ms 4956 KB Output is correct
5 Correct 24 ms 5272 KB Output is correct
6 Correct 22 ms 4956 KB Output is correct
7 Correct 15 ms 4440 KB Output is correct
8 Correct 86 ms 20352 KB Output is correct
9 Correct 82 ms 20388 KB Output is correct
10 Correct 16 ms 4440 KB Output is correct
11 Correct 191 ms 24324 KB Output is correct
12 Correct 194 ms 24324 KB Output is correct
13 Correct 165 ms 25464 KB Output is correct
14 Correct 15 ms 4460 KB Output is correct
15 Correct 142 ms 18924 KB Output is correct
16 Correct 143 ms 17924 KB Output is correct
17 Correct 144 ms 18440 KB Output is correct
18 Correct 137 ms 18532 KB Output is correct
19 Correct 226 ms 21516 KB Output is correct
20 Correct 234 ms 21508 KB Output is correct
21 Correct 96 ms 20056 KB Output is correct
22 Correct 102 ms 19464 KB Output is correct
23 Correct 130 ms 18692 KB Output is correct
24 Correct 136 ms 18708 KB Output is correct
25 Correct 190 ms 22280 KB Output is correct
26 Correct 146 ms 17668 KB Output is correct
27 Correct 154 ms 17928 KB Output is correct
28 Correct 17 ms 4184 KB Output is correct
29 Incorrect 27 ms 5036 KB Extra information in the output file
30 Halted 0 ms 0 KB -