Submission #1093617

# Submission time Handle Problem Language Result Execution time Memory
1093617 2024-09-27T06:50:28 Z CDuong Inside information (BOI21_servers) C++17
80 / 100
266 ms 26748 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) {}
};

int tpq[1000005];

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

    graph<int> g(n);
    vector<int> 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 6236 KB Output is correct
2 Correct 24 ms 6756 KB Output is correct
3 Correct 24 ms 6484 KB Output is correct
4 Correct 24 ms 6744 KB Output is correct
5 Correct 24 ms 7004 KB Output is correct
6 Correct 23 ms 6740 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 16 ms 6236 KB Output is correct
2 Correct 24 ms 6756 KB Output is correct
3 Correct 24 ms 6484 KB Output is correct
4 Correct 24 ms 6744 KB Output is correct
5 Correct 24 ms 7004 KB Output is correct
6 Correct 23 ms 6740 KB Output is correct
7 Correct 16 ms 5980 KB Output is correct
8 Incorrect 26 ms 6736 KB Extra information in the output file
9 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 16 ms 6244 KB Output is correct
2 Correct 98 ms 21596 KB Output is correct
3 Correct 87 ms 21628 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 16 ms 6244 KB Output is correct
2 Correct 98 ms 21596 KB Output is correct
3 Correct 87 ms 21628 KB Output is correct
4 Correct 16 ms 5976 KB Output is correct
5 Correct 80 ms 21628 KB Output is correct
6 Correct 65 ms 20784 KB Output is correct
7 Correct 74 ms 20760 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 16 ms 6232 KB Output is correct
2 Correct 192 ms 25444 KB Output is correct
3 Correct 192 ms 25604 KB Output is correct
4 Correct 157 ms 26632 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 16 ms 6232 KB Output is correct
2 Correct 192 ms 25444 KB Output is correct
3 Correct 192 ms 25604 KB Output is correct
4 Correct 157 ms 26632 KB Output is correct
5 Correct 16 ms 5980 KB Output is correct
6 Correct 203 ms 25520 KB Output is correct
7 Correct 170 ms 26628 KB Output is correct
8 Correct 192 ms 25308 KB Output is correct
9 Correct 204 ms 25348 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 16 ms 6232 KB Output is correct
2 Correct 156 ms 20352 KB Output is correct
3 Correct 135 ms 19108 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 16 ms 6232 KB Output is correct
2 Correct 156 ms 20352 KB Output is correct
3 Correct 135 ms 19108 KB Output is correct
4 Correct 16 ms 5976 KB Output is correct
5 Correct 152 ms 20204 KB Output is correct
6 Correct 145 ms 19208 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 16 ms 6236 KB Output is correct
2 Correct 195 ms 25464 KB Output is correct
3 Correct 191 ms 25604 KB Output is correct
4 Correct 156 ms 26748 KB Output is correct
5 Correct 16 ms 6236 KB Output is correct
6 Correct 143 ms 20192 KB Output is correct
7 Correct 148 ms 19204 KB Output is correct
8 Correct 135 ms 19716 KB Output is correct
9 Correct 141 ms 19720 KB Output is correct
10 Correct 229 ms 22872 KB Output is correct
11 Correct 233 ms 22792 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 16 ms 6236 KB Output is correct
2 Correct 195 ms 25464 KB Output is correct
3 Correct 191 ms 25604 KB Output is correct
4 Correct 156 ms 26748 KB Output is correct
5 Correct 16 ms 6236 KB Output is correct
6 Correct 143 ms 20192 KB Output is correct
7 Correct 148 ms 19204 KB Output is correct
8 Correct 135 ms 19716 KB Output is correct
9 Correct 141 ms 19720 KB Output is correct
10 Correct 229 ms 22872 KB Output is correct
11 Correct 233 ms 22792 KB Output is correct
12 Correct 16 ms 5976 KB Output is correct
13 Correct 193 ms 25452 KB Output is correct
14 Correct 175 ms 26632 KB Output is correct
15 Correct 191 ms 25352 KB Output is correct
16 Correct 185 ms 25352 KB Output is correct
17 Correct 16 ms 5976 KB Output is correct
18 Correct 147 ms 20208 KB Output is correct
19 Correct 137 ms 19204 KB Output is correct
20 Correct 135 ms 19720 KB Output is correct
21 Correct 148 ms 19720 KB Output is correct
22 Correct 231 ms 22792 KB Output is correct
23 Correct 266 ms 23044 KB Output is correct
24 Correct 254 ms 23160 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 16 ms 6212 KB Output is correct
2 Correct 24 ms 6748 KB Output is correct
3 Correct 24 ms 6492 KB Output is correct
4 Correct 24 ms 6740 KB Output is correct
5 Correct 24 ms 7008 KB Output is correct
6 Correct 23 ms 6740 KB Output is correct
7 Correct 16 ms 6236 KB Output is correct
8 Correct 88 ms 21588 KB Output is correct
9 Correct 80 ms 21664 KB Output is correct
10 Correct 15 ms 6232 KB Output is correct
11 Correct 200 ms 25568 KB Output is correct
12 Correct 196 ms 25604 KB Output is correct
13 Correct 155 ms 26612 KB Output is correct
14 Correct 16 ms 6232 KB Output is correct
15 Correct 143 ms 20196 KB Output is correct
16 Correct 149 ms 19204 KB Output is correct
17 Correct 138 ms 19716 KB Output is correct
18 Correct 141 ms 19716 KB Output is correct
19 Correct 234 ms 22792 KB Output is correct
20 Correct 231 ms 22788 KB Output is correct
21 Correct 101 ms 21512 KB Output is correct
22 Correct 105 ms 20740 KB Output is correct
23 Correct 133 ms 19916 KB Output is correct
24 Correct 124 ms 19972 KB Output is correct
25 Correct 200 ms 23508 KB Output is correct
26 Correct 144 ms 18964 KB Output is correct
27 Correct 132 ms 19088 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 16 ms 6212 KB Output is correct
2 Correct 24 ms 6748 KB Output is correct
3 Correct 24 ms 6492 KB Output is correct
4 Correct 24 ms 6740 KB Output is correct
5 Correct 24 ms 7008 KB Output is correct
6 Correct 23 ms 6740 KB Output is correct
7 Correct 16 ms 6236 KB Output is correct
8 Correct 88 ms 21588 KB Output is correct
9 Correct 80 ms 21664 KB Output is correct
10 Correct 15 ms 6232 KB Output is correct
11 Correct 200 ms 25568 KB Output is correct
12 Correct 196 ms 25604 KB Output is correct
13 Correct 155 ms 26612 KB Output is correct
14 Correct 16 ms 6232 KB Output is correct
15 Correct 143 ms 20196 KB Output is correct
16 Correct 149 ms 19204 KB Output is correct
17 Correct 138 ms 19716 KB Output is correct
18 Correct 141 ms 19716 KB Output is correct
19 Correct 234 ms 22792 KB Output is correct
20 Correct 231 ms 22788 KB Output is correct
21 Correct 101 ms 21512 KB Output is correct
22 Correct 105 ms 20740 KB Output is correct
23 Correct 133 ms 19916 KB Output is correct
24 Correct 124 ms 19972 KB Output is correct
25 Correct 200 ms 23508 KB Output is correct
26 Correct 144 ms 18964 KB Output is correct
27 Correct 132 ms 19088 KB Output is correct
28 Correct 17 ms 5980 KB Output is correct
29 Incorrect 26 ms 6772 KB Extra information in the output file
30 Halted 0 ms 0 KB -