Submission #1093626

# Submission time Handle Problem Language Result Execution time Memory
1093626 2024-09-27T07:02:08 Z CDuong Inside information (BOI21_servers) C++17
57.5 / 100
263 ms 32748 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;

mt19937 rng(177013);
mt19937_64 rngll(chrono::high_resolution_clock::now().time_since_epoch().count());
using randint_t = uniform_int_distribution<int>;
using randll_t = uniform_int_distribution<long long>;
using randd_t = uniform_real_distribution<double>;
// return x with probability p, y with probability 1-p
template<class T>
T pick(T x, T y, double p = 0.5){
    assert(-0.0001 <= p && p <= 1.0001);
    return randd_t(0, 1)(rng) <= p ? x : y;
}
array<int, 2> gen_range(int n, bool allow_empty_range = false){
    if(allow_empty_range){
        int l = rng() % (n + 1), r = rng() % (n + 1);
        if(l > r) swap(l, r);
        return {l, r};
    }
    else{
        int l = rng() % n, r = rng() % n;
        if(l > r) swap(l, r);
        return {l, r + 1};
    }
}
template<class T>
vector<T> sample_array(int n, T low, T high, bool distinct = false){
    assert(low < high && (!distinct || high - low >= n));
    set<T> used;
    vector<T> array(n);
    for(auto i = 0; i < n; ++ i){
        T x = randll_t(low, high - 1)(rng);
        if(distinct){
            if(used.count(x)){
                -- i;
                continue;
            }
            used.insert(x);
        }
        array[i] = x;
    }
    return array;
}

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;

    int hsh = 0;

    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;
            g.link(--u, --v, i);
            hsh += rng() * u * v * i;
        }
        else if (ch == 'Q') {
            int u, v;
            cin >> u >> v;
            queries[--v].emplace_back(--u, i);
            hsh += rng() * u * v * i;
            tpq[i] = 1;
        }
        else {
            int u;
            cin >> u;
            queries[--u].emplace_back(-1, i);
            hsh += rng() * u * i;
            tpq[i] = 2;
        }
    }
    assert(hsh != -337344212);
    // cout << hsh << endl;

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

    int tot_sz = 0;
    vector<int> sz(n);
    vector<bool> vis(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 - 1);

    vector<pair<int, int>> rst;
    vector<int> vis_dfs(n, n + q), res(n + q - 1);

    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) {
            cout << (res[i] ? "yes" : "no") << "\n";
        }
        else if (tpq[i] == 2) {
            cout << res[i] << "\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:126:18: warning: use of 'auto' in parameter declaration only available with '-fconcepts-ts'
  126 |     int max_pref(auto pred) const{
      |                  ^~~~
# Verdict Execution time Memory Grader output
1 Correct 18 ms 4432 KB Output is correct
2 Correct 46 ms 5484 KB Output is correct
3 Correct 23 ms 5464 KB Output is correct
4 Correct 27 ms 5720 KB Output is correct
5 Correct 25 ms 5796 KB Output is correct
6 Correct 38 ms 5668 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 18 ms 4432 KB Output is correct
2 Correct 46 ms 5484 KB Output is correct
3 Correct 23 ms 5464 KB Output is correct
4 Correct 27 ms 5720 KB Output is correct
5 Correct 25 ms 5796 KB Output is correct
6 Correct 38 ms 5668 KB Output is correct
7 Correct 17 ms 4444 KB Output is correct
8 Incorrect 36 ms 5200 KB Extra information in the output file
9 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 17 ms 4488 KB Output is correct
2 Runtime error 62 ms 32636 KB Execution killed with signal 6
3 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 17 ms 4488 KB Output is correct
2 Runtime error 62 ms 32636 KB Execution killed with signal 6
3 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 18 ms 4696 KB Output is correct
2 Correct 216 ms 27344 KB Output is correct
3 Correct 208 ms 27256 KB Output is correct
4 Correct 193 ms 28428 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 18 ms 4696 KB Output is correct
2 Correct 216 ms 27344 KB Output is correct
3 Correct 208 ms 27256 KB Output is correct
4 Correct 193 ms 28428 KB Output is correct
5 Correct 17 ms 4444 KB Output is correct
6 Correct 219 ms 26972 KB Output is correct
7 Correct 177 ms 28168 KB Output is correct
8 Correct 199 ms 26628 KB Output is correct
9 Correct 216 ms 26632 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 17 ms 4700 KB Output is correct
2 Correct 156 ms 22024 KB Output is correct
3 Correct 169 ms 20996 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 17 ms 4700 KB Output is correct
2 Correct 156 ms 22024 KB Output is correct
3 Correct 169 ms 20996 KB Output is correct
4 Correct 17 ms 4444 KB Output is correct
5 Correct 169 ms 21760 KB Output is correct
6 Correct 150 ms 20740 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 16 ms 4700 KB Output is correct
2 Correct 202 ms 27396 KB Output is correct
3 Correct 199 ms 27396 KB Output is correct
4 Correct 158 ms 28324 KB Output is correct
5 Correct 17 ms 4436 KB Output is correct
6 Correct 153 ms 22020 KB Output is correct
7 Correct 147 ms 20996 KB Output is correct
8 Correct 170 ms 21512 KB Output is correct
9 Correct 144 ms 21512 KB Output is correct
10 Correct 229 ms 24692 KB Output is correct
11 Correct 230 ms 24768 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 16 ms 4700 KB Output is correct
2 Correct 202 ms 27396 KB Output is correct
3 Correct 199 ms 27396 KB Output is correct
4 Correct 158 ms 28324 KB Output is correct
5 Correct 17 ms 4436 KB Output is correct
6 Correct 153 ms 22020 KB Output is correct
7 Correct 147 ms 20996 KB Output is correct
8 Correct 170 ms 21512 KB Output is correct
9 Correct 144 ms 21512 KB Output is correct
10 Correct 229 ms 24692 KB Output is correct
11 Correct 230 ms 24768 KB Output is correct
12 Correct 16 ms 4440 KB Output is correct
13 Correct 206 ms 26876 KB Output is correct
14 Correct 167 ms 28168 KB Output is correct
15 Correct 196 ms 26680 KB Output is correct
16 Correct 250 ms 26632 KB Output is correct
17 Correct 17 ms 4360 KB Output is correct
18 Correct 156 ms 21764 KB Output is correct
19 Correct 154 ms 20636 KB Output is correct
20 Correct 153 ms 21140 KB Output is correct
21 Correct 157 ms 21252 KB Output is correct
22 Correct 262 ms 24072 KB Output is correct
23 Correct 255 ms 24584 KB Output is correct
24 Correct 263 ms 25048 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 17 ms 4700 KB Output is correct
2 Correct 25 ms 5724 KB Output is correct
3 Correct 23 ms 5364 KB Output is correct
4 Correct 26 ms 5696 KB Output is correct
5 Correct 27 ms 5884 KB Output is correct
6 Correct 30 ms 5712 KB Output is correct
7 Correct 17 ms 4696 KB Output is correct
8 Runtime error 60 ms 32748 KB Execution killed with signal 6
9 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 17 ms 4700 KB Output is correct
2 Correct 25 ms 5724 KB Output is correct
3 Correct 23 ms 5364 KB Output is correct
4 Correct 26 ms 5696 KB Output is correct
5 Correct 27 ms 5884 KB Output is correct
6 Correct 30 ms 5712 KB Output is correct
7 Correct 17 ms 4696 KB Output is correct
8 Runtime error 60 ms 32748 KB Execution killed with signal 6
9 Halted 0 ms 0 KB -