Submission #872811

# Submission time Handle Problem Language Result Execution time Memory
872811 2023-11-13T20:43:24 Z bobbilyking Dynamic Diameter (CEOI19_diameter) C++17
25 / 100
1309 ms 72388 KB
// annoying impl i dont want to deal with rn

#pragma GCC target ("avx2")
#pragma GCC optimize ("O3")
#pragma GCC optimize ("unroll-loops")

#include<bits/stdc++.h>
#include<math.h>
using namespace std;

typedef long long int ll;
typedef long double ld;
typedef pair<ll, ll> pl;

#define K first
#define V second
#define G(x) ll x; cin >> x;
#define GD(x) ld x; cin >> x;
#define GS(s) string s; cin >> s;
#define EX(x) { cout << x << '\n'; exit(0); }
#define A(a) (a).begin(), (a).end()
#define F(i, l, r) for (ll i = (l); i < r; ++i)

#define NN 100010
#define M 1000000007 // 998244353

vector<pl> adj[NN];

ll belong[NN], w[NN]; // maps original edge -> which edge it belongs to now

ll down[NN], par[NN]; // in the new tree, the node below edge I = down[i], and parent of node X in new tree
ll parEdge[NN]; // wehn traversing par, what is the edge I use
ll curw[NN]; // current weight of edge 

ll edgeidx = 0; 

void dfs(ll i, ll p, ll vpar) {
    ll children = 0;
    for (auto [x, _]: adj[i]) if (x-p) children++;
    if (children == 1) {
        for (auto [x, eidx]: adj[i]) if (x-p) {
            belong[eidx] = edgeidx;
            dfs(x, i, vpar);
        }
    } else {
        if (i != 1) {
            down[edgeidx] = i;
            par[i] = vpar;
            parEdge[i] = edgeidx;
            edgeidx++;
        }
        for (auto [x, eidx]: adj[i]) if (x-p) {
            belong[eidx] = edgeidx;
            dfs(x, i, i);
        }
    }
}

multiset<ll> all_answer; // all subtree answers
ll curans[NN]; //current answer

multiset<ll> childrenPull[NN]; // the curD's of my children

map<ll, ll> children[NN]; // children -> curD

ll ROOT(ll i) {
    return par[i] == i || par[i] == -1;
}
void multiset_erase(multiset<ll>& a, ll value){
    assert(a.find(value) != a.end());
    a.erase(a.find(value));
}

ll getOneEdge(ll i) { // CANNOT be 1
    assert(childrenPull[i].size() != 1); 
    if (childrenPull[i].size() == 0) return 0;
    return *childrenPull[i].rbegin();
}

void recompute(ll i, ll modified) {
    // cout << "asking to recompute " << i << " with child " << modified << " modified " << endl; 
    // cout << "lol " << i << " " << modified << endl;
    // recomptues maximal down

    // cout << "LOL " << childrenPull[i].size() << ": ";
    // for (auto x: childrenPull[i]) cout << x << " , "; cout << endl;

    assert(children[i].count(modified));
    multiset_erase(childrenPull[i], children[i][modified]);
    children[i][modified] = curw[parEdge[modified]] + getOneEdge(modified);
    childrenPull[i].insert(children[i][modified]);

    // cout << "OK: recomputed. My things are:  \n";
    // for (const auto [k, v]: children[i]) cout << k << ": " << v << endl;
    // cout << "children pull: ";
    // for (const auto x: childrenPull[i]) cout << x << " "; cout << endl;
    
    // cout << parEdge[modified] << ":WTF " << curw[parEdge[modified]] << endl;

    assert(children[i].size() == childrenPull[i].size());

    // cout << "Yo " << endl;
    // recomputes answer
    multiset_erase(all_answer, curans[i]);

    if (childrenPull[i].size() <= 1) 
        curans[i] = getOneEdge(i);
    else {
        // cout << "wtf " << endl;
        auto v = childrenPull[i].rbegin();
        ll t = *v;
        
        v = ++childrenPull[i].rbegin();
        t += *v;

        // cout << "AFTER " << t << endl;
        curans[i] = t;
    }
    // cout << "Ya " << endl;

    all_answer.insert(curans[i]);
    if (!ROOT(i)) recompute(par[i], i);
}

int main(){
//    freopen("a.in", "r", stdin);
//    freopen("a.out", "w", stdout);

    ios_base::sync_with_stdio(false); cin.tie(0);
    cout << fixed << setprecision(20);
    G(n) G(q) G(W)
    memset(par, -1, sizeof par);
    vector<ll> weights(n-1);
    vector<pl> shits;
    F(i, 0, n-1) {
        G(x) G(y) cin >> weights[i];
        adj[x].emplace_back(y, i);
        adj[y].emplace_back(x, i);
        shits.emplace_back(x, y);
    }


    // We want to dfs from a non-leaf root node.
    // Unless n=2; then it's trivial.

    if (n==2) {
        ll last = 0;
        while (q--) {
            G(d) G(e)
            d = (d + last)%(n-1);
            e = (e + last)%W;
            last = e;
            cout << last << '\n';
        }
        exit(0);    
    }

    F(root, 1, n+1) if (adj[root].size() >1) {
        dfs(root, -1, root); break;
    }

    F(i, 1, n+1) if (~par[i]) {
        if (!ROOT(i)) {
            children[par[i]][i] = 0;
            childrenPull[par[i]].insert(0);
        }
        all_answer.insert(curans[i] = 0);

        // cout << "Alive: " << i << endl;
    }
    // F(i, 0, n-1) cout << i << " -> " << belong[i] << endl;

    auto upd = [&](ll i, ll we) {
        ll cur = belong[i];
        curw[cur] -= w[i];
        w[i] = we;
        curw[cur] += w[i];

        // cout << "just updated, thought new cur " << cur << " is " << curw[cur] << endl;

        // cout << "wee wee " << i << " " << we << endl;
        // cout << "THIS BELONGS TO " << belong[i] << endl;
        // cout << "BELONG I SPANS " << down[cur] << "TO " << par[down[cur]] << endl;
        assert(par[down[cur]] != down[cur]);
        recompute(par[down[cur]], down[cur]);
    };

    F(i, 0, n-1) upd(i, weights[i]);

    ll last = 0;
    
    // cout << "current: " << endl;
    // F(k, 1, n+1) cout << k << ": " << curans[k] << endl;


    while (q--) {
        G(d) G(e)
        d = (d + last)%(n-1);
        e = (e + last)%W;
        // cout << "Modifying " << d << " to " << e << endl;

        // if (q == 0){
        //     F(i, 0, n-1) {
        //         cout << shits[i].K << " " << shits[i].V << " " << w[i] << endl;
        //     }
        //     F(j, 0, edgeidx) {
        //         cout << "FAKE EDGE " << j << " FROM " << down[j] << " to " << par[down[j]] << ": " << curw[j] << endl;
        //     }
        // }

        upd(d, e);
        // cout << "current: " << endl;
        // F(k, 1, n+1) cout << k << ": " << curans[k] << endl;

        last = *all_answer.rbegin();
        cout << last << '\n';
    }
}
# Verdict Execution time Memory Grader output
1 Incorrect 3 ms 17496 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 3 ms 17496 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 4 ms 17496 KB Output is correct
2 Correct 5 ms 17500 KB Output is correct
3 Correct 4 ms 17476 KB Output is correct
4 Correct 12 ms 17760 KB Output is correct
5 Correct 43 ms 18000 KB Output is correct
6 Correct 4 ms 17496 KB Output is correct
7 Correct 5 ms 17756 KB Output is correct
8 Correct 4 ms 17756 KB Output is correct
9 Correct 5 ms 17756 KB Output is correct
10 Correct 16 ms 18032 KB Output is correct
11 Correct 62 ms 18984 KB Output is correct
12 Correct 9 ms 18780 KB Output is correct
13 Correct 9 ms 18780 KB Output is correct
14 Correct 11 ms 19032 KB Output is correct
15 Correct 30 ms 19340 KB Output is correct
16 Correct 100 ms 20308 KB Output is correct
17 Correct 180 ms 41400 KB Output is correct
18 Correct 183 ms 41392 KB Output is correct
19 Correct 197 ms 41568 KB Output is correct
20 Correct 220 ms 41908 KB Output is correct
21 Correct 465 ms 43220 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 6 ms 17752 KB Output is correct
2 Correct 18 ms 17756 KB Output is correct
3 Correct 68 ms 18064 KB Output is correct
4 Correct 128 ms 18256 KB Output is correct
5 Correct 40 ms 19924 KB Output is correct
6 Correct 63 ms 19928 KB Output is correct
7 Correct 140 ms 20228 KB Output is correct
8 Correct 269 ms 20684 KB Output is correct
9 Correct 256 ms 29388 KB Output is correct
10 Correct 286 ms 29424 KB Output is correct
11 Correct 404 ms 29684 KB Output is correct
12 Correct 556 ms 30444 KB Output is correct
13 Correct 620 ms 41164 KB Output is correct
14 Correct 628 ms 41148 KB Output is correct
15 Correct 778 ms 41668 KB Output is correct
16 Correct 957 ms 41944 KB Output is correct
17 Correct 1309 ms 41668 KB Output is correct
# Verdict Execution time Memory Grader output
1 Runtime error 96 ms 72388 KB Execution killed with signal 6
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 3 ms 17496 KB Output isn't correct
2 Halted 0 ms 0 KB -