Submission #1004734

#TimeUsernameProblemLanguageResultExecution timeMemory
1004734vjudge1Dynamic Diameter (CEOI19_diameter)C++17
31 / 100
5074 ms62652 KiB
#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using vi = vector<int>;
using ii = pair<int, int>;

struct AINT {
    int n;
    vector<ll> V;

    AINT() {}

    AINT(int N) : n(N), V(N, 0) {}

    void update(int st, int dr, ll v) {
        for(int i = st; i <= dr; ++i) V[i] += v;
    }

    ll query(int st, int dr) {
        ll re = 0;
        for(int i = st; i <= dr; ++i) re = max(re, V[i]);
        return re;
    }
};

namespace tree {
    int n;
    int tmr = 0;
    vi niv, euler, on, sz;
    vector<ll> cost;
    vector<vector<ii> > L;

    multiset<ll> Profi;
    struct InfoCent {
        multiset<ll> V;
        ll profit = 0;
        void change(ll a, ll b) {
            Profi.erase(Profi.find(profit));
            V.erase(V.find(a));
            V.insert(b);

            ll vm = *V.rbegin();
            profit = vm;
            V.erase(V.find(vm));
            if(!V.empty()) 
                profit += *V.rbegin();
            V.insert(vm);

            Profi.insert(profit);
        }
    };

    vector<InfoCent> Info;

    struct comp {
        int st, dr, cent;
        ll val;
    };
    vector<comp> Componente;

    vector< vector<ii> > SegMuchie;
    vector<vi> CompMuchie;

    AINT Sol;

    void init(int N) {
        n = N;
        niv.assign(N, 0);
        on.assign(N, 1);
        sz.assign(N, 0);
        cost.assign(N, 0);
        L.resize(N);
        Info.resize(N);
        SegMuchie.resize(N);
        CompMuchie.resize(N);
    }

    void add_edge(int u, int v, int id) {
        L[u].push_back({v, id});
        L[v].push_back({u, id});
    }



    void init() {
        function<void(int, int)> dfs_sz = [&](int u, int p) {
            sz[u] = 1;
            for(auto [it, id] : L[u])
                if(it != p && on[it]) {
                    dfs_sz(it, u);
                    sz[u] += sz[it];
                }
        };

        function<int(int, int, int)> find_c = [&](int u, int p, int sz_lim) {
            for(auto [it, id] : L[u])
                if(on[it] && it != p && 2 * sz[it] > sz_lim) return find_c(it, u, sz_lim);
            return u;
        };

        function<void(int, int, int, int)> dfs_comp = [&](int u, int p, int id_par, int cur_comp) {
            int in = tmr;
            int nr_fii = 0;
            for(auto [it, id] : L[u]) {
                if(it == p || !on[it]) continue;
                ++nr_fii;
                dfs_comp(it, u, id, cur_comp);
            }
            if(!nr_fii) { /// sunt o frunza, ++tmr!
                ++tmr;
            }
            int out = tmr - 1;
            ///id_par afecteaza {in, out}
            SegMuchie[id_par].push_back({in, out});
            CompMuchie[id_par].push_back(cur_comp);
        };

        function<void(int, int)> desc_cent = [&](int u, int parc) {
            Profi.insert(0);
            dfs_sz(u, -1);
            int c = find_c(u, -1, sz[u]);
            on[c] = 0;
            for(auto [it, id] : L[c]) {
                if(on[it]) {
                    ///componenta noua
                    int eu = Componente.size();
                    int in = tmr;
                    dfs_comp(it, c, id, eu);
                    int out = tmr - 1;
                    Componente.push_back({in, out, c, 0});
                    Info[c].V.insert(0);
                }
            }
            for(auto [it, id] : L[c]) {
                if(on[it]) {
                    desc_cent(it, c);
                }
            }
        };

        desc_cent(0, -1);
        Sol = AINT(tmr); 
    }

    void update(int id, ll w) {
        w -= cost[id];
        cost[id] += w;
        for(auto [st, dr] : SegMuchie[id]) {
            Sol.update(st, dr, w);
        }
        for(auto comp : CompMuchie[id]) {
            auto &[st, dr, cent, val] = Componente[comp];
            ll v2 = Sol.query(st, dr);
            Info[cent].change(val, v2);
            val = v2;
        }
    }

    ll diam() {
        return *Profi.rbegin();
    }
};

struct edge {
    int u, v;
    ll w;
};

int main() {
    int n, q;
    ll w_max;
    cin >> n >> q >> w_max;
    tree::init(n);
    vector<edge> E;
    for(int i = 1; i < n; ++i) {
        int u, v;
        ll w;
        cin >> u >> v >> w;
        --u; --v;
        E.push_back({u, v, w});
        tree::add_edge(u, v, i - 1);
    }
    tree::init();
    for(int i = 0; i < E.size(); ++i)
        tree::update(i, E[i].w);
    ll last = 0;
    for(int i = 0; i < q; ++i) {
        ll d, e;
        cin >> d >> e;
        d = (d + last) % (n - 1);
        e = (e + last) % w_max;
        tree::update((int)d, e);
        cout << (last = tree::diam()) << "\n";
    }
    return 0;
}

Compilation message (stderr)

diameter.cpp: In function 'int main()':
diameter.cpp:186:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<edge>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  186 |     for(int i = 0; i < E.size(); ++i)
      |                    ~~^~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...