답안 #895894

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
895894 2023-12-31T03:40:45 Z math_rabbit_1028 Dynamic Diameter (CEOI19_diameter) C++14
0 / 100
2707 ms 1048576 KB
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef struct {
    int idx;
    ll val;
} pil;
const ll MOD = 998244353;

int n, q;
ll w;
ll edges[101010][3];
vector<pil> adj[101010];
int ch[101010], sz[101010];

struct subtree {
    int cent, tot, r;
    vector<int> ord;
    map<int, int> in, out, depth, table[20], child;
    map<int, ll> dis;

    void ett(int v, int par = -1) {
        ord[++r] = v; in[v] = r;
        for (int i = 0; i < adj[v].size(); i++) {
            int u = adj[v][i].idx;
            if (u == par) continue;
            if (ch[u] == 1) continue;
            dis[u] = dis[v] + adj[v][i].val;
            depth[u] = depth[v] + 1;
            table[0][u] = v;
            ett(u, v);
        }
        out[v] = r;
    }

    int get_par(int v, int h) {
        for (int k = 0; k < 20; k++) {
            if (h & (1<<k)) v = table[k][v];
       }
        return v;
    }

    struct maxseg {
        vector<pil> tree;
        vector<ll> lazy;

        pil mer(pil lt, pil rt) {
            if (lt.val > rt.val) return lt;
            if (lt.val < rt.val) return rt;
            if (lt.val == rt.val) {
                if (lt.idx > rt.idx) return lt;
                else return rt;
            }
        }

        void prop(int v) {
            tree[v].val += lazy[v];
            lazy[2*v] += lazy[v];
            lazy[2*v+1] += lazy[v];
            lazy[v] = 0;
        }

        void init(int v, int st, int ed, vector<int>* ord, map<int, ll>* dis) {
            if (st == ed) {
                tree[v] = {(*ord)[st], (*dis)[(*ord)[st]]};
                lazy[v] = 0;
                return;
            }
            int mid = (st + ed) / 2;
            init(2*v, st, mid, ord, dis);
            init(2*v+1, mid+1, ed, ord, dis);
            tree[v] = mer(tree[2*v], tree[2*v+1]);
        }

        void upd(int v, int st, int ed, int lt, int rt, ll diff) {
            prop(v);
            if (lt <= st && ed <= rt) {
                lazy[v] = diff;
                prop(v);
                return;
            }
            if (st > rt || lt > ed) return;
            int mid = (st + ed) / 2;
            upd(2*v, st, mid, lt, rt, diff);
            upd(2*v+1, mid+1, ed, lt, rt, diff);
            tree[v] = mer(tree[2*v], tree[2*v+1]);
        }

        pil get(int v, int st, int ed, int lt, int rt) {
            prop(v);
            if (lt <= st && ed <= rt) return tree[v];
            if (st > rt || lt > ed) return {0, 0};
            int mid = (st + ed) / 2;
            return mer(get(2*v, st, mid, lt, rt), get(2*v+1, mid+1, ed, lt, rt));
        }
    } seg;

    void init() {
        r = 0;
        for (int i = 0; i <= tot; i++) ord.push_back(0);
        seg.tree.resize(4*tot);
        seg.lazy.resize(4*tot);

        ett(cent);

        for (int k = 1; k < 20; k++) {
            for (auto iter = table[k-1].begin(); iter != table[k-1].end(); iter++) {
                table[k][iter->first] = (table[k-1][iter->second]);
            }
        }

        seg.init(1, 1, tot, &ord, &dis);
    }

    int update(int d, ll e) {
        int v = (depth[edges[d][0]] > depth[edges[d][1]] ? edges[d][0] : edges[d][1]);
        seg.upd(1, 1, tot, in[v], out[v], e - edges[d][2]);
        return child[get_par(v, depth[v] - 1)];
    }

    int get(ll* dst) {
        pil x = seg.get(1, 1, tot, 1, tot);
        int u = get_par(x.idx, depth[x.idx] - 1);
        pil y = seg.get(1, 1, tot, 1, in[u]-1);
        pil z = seg.get(1, 1, tot, out[u]+1, tot);
        *dst = max(*dst, x.val + max(y.val, z.val));
        return child[u];
    }

} sub[101010];

void get_sz(int v, int par = -1) {
    sz[v] = 1;
    for (int i = 0; i < adj[v].size(); i++) {
        int u = adj[v][i].idx;
        if (ch[u] == 1) continue;
        if (u == par) continue;
        get_sz(u, v);
        sz[v] += sz[u];
    }
}

int get_cent(int tot, int v, int par = -1) {
    for (int i = 0; i < adj[v].size(); i++) {
        int u = adj[v][i].idx;
        if (ch[u] == 1) continue;
        if (u == par) continue;
        if (sz[u] * 2 > tot) return get_cent(tot, u, v);
    }
    return v;
}

int cent(int v, int tot) {
    get_sz(v);
    v = get_cent(tot, v);
    get_sz(v);

    sub[v].tot = tot;
    sub[v].cent = v;
    sub[v].init();

    ch[v] = 1;
    for (int i = 0; i < adj[v].size(); i++) {
        int u = adj[v][i].idx;
        if (ch[u] == 1) continue;
        sub[v].child[u] = cent(u, sz[u]);
    }

    return v;
}

void update(int cent, int d, ll e) {
    while (sub[cent].tot > 1) {
        cent = sub[cent].update(d, e);
    }
}

void get(int cent, ll* dst) {
    while (sub[cent].tot > 1) {
        cent = sub[cent].get(dst);
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    cin >> n >> q >> w;

    for (int i = 1; i < n; i++) {
        int a, b; ll c;
        cin >> a >> b >> c;
        edges[i][0] = a;
        edges[i][1] = b;
        edges[i][2] = c;
        adj[a].push_back({b, c});
        adj[b].push_back({a, c});
    }

    int CENT = cent(1, n);

    ll last = 0;
    while (q--) {
        int d; ll e;
        cin >> d >> e;

        d = (d + last) % (n - 1) + 1;
        e = (e + last) % w;

        update(CENT, d, e);
        edges[d][2] = e;

        last = -1;
        get(CENT, &last);
        cout << last << "\n";

        //for (int i = 1; i < n; i++) cout << sub[CENT].seg.get(1, 1, n, i, i).val << " "; cout << "\n";
        //for (int i = 1; i < n; i++) cout << sub[CENT].seg.get(1, 1, n, i, i).idx << " "; cout << "\n";
    }

    return 0;
}

Compilation message

diameter.cpp: In member function 'void subtree::ett(int, int)':
diameter.cpp:24:27: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<pil>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   24 |         for (int i = 0; i < adj[v].size(); i++) {
      |                         ~~^~~~~~~~~~~~~~~
diameter.cpp: In function 'void get_sz(int, int)':
diameter.cpp:134:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<pil>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  134 |     for (int i = 0; i < adj[v].size(); i++) {
      |                     ~~^~~~~~~~~~~~~~~
diameter.cpp: In function 'int get_cent(int, int, int)':
diameter.cpp:144:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<pil>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  144 |     for (int i = 0; i < adj[v].size(); i++) {
      |                     ~~^~~~~~~~~~~~~~~
diameter.cpp: In function 'int cent(int, int)':
diameter.cpp:163:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<pil>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  163 |     for (int i = 0; i < adj[v].size(); i++) {
      |                     ~~^~~~~~~~~~~~~~~
diameter.cpp: In member function 'pil subtree::maxseg::mer(pil, pil)':
diameter.cpp:54:9: warning: control reaches end of non-void function [-Wreturn-type]
   54 |         }
      |         ^
# 결과 실행 시간 메모리 Grader output
1 Runtime error 134 ms 267060 KB Execution killed with signal 6
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 134 ms 267060 KB Execution killed with signal 6
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 122 ms 267264 KB Execution killed with signal 6
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 136 ms 286548 KB Execution killed with signal 11
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 2707 ms 1048576 KB Execution killed with signal 9
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Runtime error 134 ms 267060 KB Execution killed with signal 6
2 Halted 0 ms 0 KB -