답안 #703201

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
703201 2023-02-26T14:24:03 Z Nursik Paths (RMI21_paths) C++14
100 / 100
549 ms 34252 KB
#include <iostream>
#include <fstream>
#include <iomanip>
#include <vector>
#include <set>
#include <map>
#include <cstring>
#include <string>
#include <cmath>
#include <cassert>
#include <ctime>
#include <algorithm>
#include <sstream>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <cstdlib>
#include <cstdio>
#include <iterator>
#include <functional>
#include <unordered_set>
#include <unordered_map>
#include <stdio.h>
#include <bitset>
#include <cstdint>
#include <cassert>
#include <functional>
#include <complex>
#include <random>

using namespace std;
 
#define ll long long
#define pb push_back
#define mp make_pair
#define f first
#define s second
#define ld long double
 
const ll maxn = 1e5 + 10, maxm = 3e5 + 1;
const ll mod = 1e9 + 7, cmod = 998244353, inf = 1e9, blcok = 400, p2 = 31;
const ld eps = 1e-9;

ll rng(){
    return (((ll)rand() << 15) + rand());
}
struct node{
    int sz;
    ll sum;
    ll key, prior, kol;
    node *l, *r;
    node(ll x){
        key = x, prior = rng(), kol = 1;
        sum = x; sz = 1;
        l = r = nullptr;
    }
};
struct treap{
    int getsz(node *v){
        return (v == nullptr ? 0 : v->sz);
    }
    ll getsum(node *v){
        return (v == nullptr ? 0 : v->sum);
    }
    void pull(node *v){
        v->sum = getsum(v->l) + getsum(v->r) + v->kol * v->key;
        v->sz = getsz(v->l) + getsz(v->r) + v->kol;
    }
    pair<node*, node*> split(node* &v, ll x){
        if (v == nullptr)
            return mp(nullptr, nullptr);
        if (v->key < x){
            pair<node*, node*> splitted = split(v->r, x);
            v->r = splitted.f;
            pull(v);
            return mp(v, splitted.s);
        }
        else{
            pair<node*, node*> splitted = split(v->l, x);
            v->l = splitted.s;
            pull(v);
            return mp(splitted.f, v);
        }
    }
    node* merge(node *l, node *r){
        if (l == nullptr || r == nullptr)
            return (l ? l : r);
        if (l->prior > r->prior){
            l->r = merge(l->r, r);
            pull(l);
            return l;
        }
        else{
            r->l = merge(l, r->l);
            pull(r);
            return r;
        }
    }
    ll get(node* &v, ll k){
        if (k == 0)
            return 0;
        if (getsz(v->l) + v->kol <= k){
            return getsum(v->l) + v->kol * v->key + get(v->r, k - getsz(v->l) - v->kol);
        }
        else if (getsz(v->l) <= k){
            return getsum(v->l) + (k - getsz(v->l)) * v->key;
        }
        else{
            return get(v->l, k);
        }
    }
} t;

node *root;
int n, k, leafs;
ll dp[maxn], ans[maxn];
vector<pair<int, int>> g[maxn];
vector<ll> vec;
void add(ll med){
    pair<node*, node*> spl1 = t.split(root, med);
    pair<node*, node*> spl2 = t.split(spl1.s, med + 1);
    if (spl2.f != nullptr){
        spl2.f->kol += 1;
        spl2.f->sz += 1;
        spl2.f->sum += med;
    }
    else{
        spl2.f = new node(med);
    }
    root = t.merge(t.merge(spl1.f, spl2.f), spl2.s);
}
void del(ll med){
    pair<node*, node*> spl1 = t.split(root, med);
    pair<node*, node*> spl2 = t.split(spl1.s, med + 1);
    if (spl2.f != nullptr){
        spl2.f->kol -= 1;
        spl2.f->sz -= 1;
        spl2.f->sum -= med;
        if (spl2.f->kol == 0){
            spl2.f = nullptr;
        }
    }
    root = t.merge(t.merge(spl1.f, spl2.f), spl2.s);
}
void dfs(int v = 1, int p = 0){
    dp[v] = 0;
    for (auto to : g[v]){
        int go = to.f, w = to.s;
        if (go != p){
            dfs(go, v);
            dp[v] = max(dp[v], dp[go] + w);
        }
    }
    int is = 0;
    for (auto to : g[v]){
        int go = to.f, w = to.s;
        if (go != p){
            if (dp[v] != dp[go] + w || is){
                ll z = dp[go] + w;
                add(z);
            }
            else{
                is = 1;
            }
        }
    }
}
void dfs2(int v = 1, int p = 0, int type = 0){
    vector<ll> sadd, sdel;
    int is = 0;
    for (auto to : g[v]){
        ll go = to.f, w = to.s;
        if (go != p){
            if (dp[v] != dp[go] + w || is){
                ll z = dp[go] + w;
                del(z);
                sadd.pb(z);
            }
            else{
                is = 1;
            }
        }
    }
   // cout << root->sum << '\n';
    for (auto to : g[v]){
        ll go = to.f, w = to.s;
        dp[v] = max(dp[v], dp[go] + w);
    }
    is = 0;
    for (auto to : g[v]){
        int go = to.f, w = to.s;
        if (dp[v] != dp[go] + w || is){
            ll z = dp[go] + w;
            if (go == p && type == 1){
                ll z2 = dp[go];
                del(z2);
                sadd.pb(z2);
            }
            add(z);
            sdel.pb(z);
        }
        else{
            if (go == p && type == 1){
                ll z = dp[go];
                del(z);
               // cout << "kek\n";
                sadd.pb(z);
            }
            is = 1;
        }
    }
    int lakers = t.getsz(root);
    ans[v] = dp[v] + t.getsum(root) - t.get(root, lakers - (k - 1));
    multiset<ll> setik;
    for (auto to : g[v]){
        ll go = to.f, w = to.s;
        setik.insert(dp[go] + w);
    }
    for (auto to : g[v]){
        int go = to.f, w = to.s;
        if (go != p){
            ll prevdp = dp[v];
            ll z = dp[go] + w;
            int isdel = 0;
            if (*setik.rbegin() != z){
                del(z);
                isdel = 1;
            }
            setik.erase(setik.find(z));
            if (setik.size() == 0){
                dp[v] = 0;
            }
            else{
                dp[v] = *setik.rbegin();
            }
            dfs2(go, v, !isdel);
            setik.insert(z);
            if (isdel){
                add(z);
            }
            dp[v] = prevdp;
        }
    }
    for (auto it : sadd){
        add(it);
    }
    for (auto it : sdel){
        del(it);
    }
    dp[v] = -inf;
    for (auto to : g[v]){
        int go = to.f, w = to.s;
        if (go != p){
            dp[v] = max(dp[v], dp[go] + w);
        }
    }
}
int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0);
   // freopen("paths.in", "r", stdin);
   // freopen("paths.out", "w", stdout);
    cin >> n >> k;
    ll allsum = 0;
    for (int u, v, c, i = 1; i < n; ++i){
        cin >> u >> v >> c;
        g[u].pb(mp(v, c));
        g[v].pb(mp(u, c));
        allsum += c;
    }
    for (int i = 1; i <= n; ++i){
        leafs += ((int)g[i].size() == 1);
    }
    if (leafs <= k){
        for (int i = 1; i <= n; ++i){
            cout << allsum << " ";
        }
        exit(0);
    }
    dfs();
   // cout << dp[1] + t.getsum(root) - t.get(root, t.getsz(root) - (k - 1));
   // exit(0);
    dfs2();
    for (int i = 1; i <= n; ++i){
        cout << ans[i] << " ";
    }
}
/*
*/

# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 2644 KB Output is correct
2 Correct 2 ms 2644 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 2644 KB Output is correct
2 Correct 2 ms 2644 KB Output is correct
3 Correct 2 ms 2644 KB Output is correct
4 Correct 2 ms 2644 KB Output is correct
5 Correct 2 ms 2680 KB Output is correct
6 Correct 2 ms 2644 KB Output is correct
7 Correct 2 ms 2644 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 2644 KB Output is correct
2 Correct 2 ms 2644 KB Output is correct
3 Correct 2 ms 2644 KB Output is correct
4 Correct 2 ms 2644 KB Output is correct
5 Correct 2 ms 2680 KB Output is correct
6 Correct 2 ms 2644 KB Output is correct
7 Correct 2 ms 2644 KB Output is correct
8 Correct 5 ms 2900 KB Output is correct
9 Correct 4 ms 3072 KB Output is correct
10 Correct 3 ms 2888 KB Output is correct
11 Correct 5 ms 2900 KB Output is correct
12 Correct 4 ms 2812 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 2644 KB Output is correct
2 Correct 2 ms 2644 KB Output is correct
3 Correct 2 ms 2644 KB Output is correct
4 Correct 2 ms 2644 KB Output is correct
5 Correct 2 ms 2680 KB Output is correct
6 Correct 2 ms 2644 KB Output is correct
7 Correct 2 ms 2644 KB Output is correct
8 Correct 5 ms 2900 KB Output is correct
9 Correct 4 ms 3072 KB Output is correct
10 Correct 3 ms 2888 KB Output is correct
11 Correct 5 ms 2900 KB Output is correct
12 Correct 4 ms 2812 KB Output is correct
13 Correct 7 ms 3156 KB Output is correct
14 Correct 6 ms 3284 KB Output is correct
15 Correct 6 ms 3200 KB Output is correct
16 Correct 10 ms 3152 KB Output is correct
17 Correct 6 ms 3028 KB Output is correct
18 Correct 6 ms 3072 KB Output is correct
19 Correct 8 ms 3068 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 507 ms 25392 KB Output is correct
2 Correct 491 ms 31108 KB Output is correct
3 Correct 295 ms 22600 KB Output is correct
4 Correct 520 ms 26356 KB Output is correct
5 Correct 504 ms 28032 KB Output is correct
6 Correct 545 ms 27240 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 1 ms 2644 KB Output is correct
2 Correct 2 ms 2644 KB Output is correct
3 Correct 2 ms 2644 KB Output is correct
4 Correct 2 ms 2644 KB Output is correct
5 Correct 2 ms 2680 KB Output is correct
6 Correct 2 ms 2644 KB Output is correct
7 Correct 2 ms 2644 KB Output is correct
8 Correct 5 ms 2900 KB Output is correct
9 Correct 4 ms 3072 KB Output is correct
10 Correct 3 ms 2888 KB Output is correct
11 Correct 5 ms 2900 KB Output is correct
12 Correct 4 ms 2812 KB Output is correct
13 Correct 7 ms 3156 KB Output is correct
14 Correct 6 ms 3284 KB Output is correct
15 Correct 6 ms 3200 KB Output is correct
16 Correct 10 ms 3152 KB Output is correct
17 Correct 6 ms 3028 KB Output is correct
18 Correct 6 ms 3072 KB Output is correct
19 Correct 8 ms 3068 KB Output is correct
20 Correct 507 ms 25392 KB Output is correct
21 Correct 491 ms 31108 KB Output is correct
22 Correct 295 ms 22600 KB Output is correct
23 Correct 520 ms 26356 KB Output is correct
24 Correct 504 ms 28032 KB Output is correct
25 Correct 545 ms 27240 KB Output is correct
26 Correct 549 ms 27268 KB Output is correct
27 Correct 485 ms 32156 KB Output is correct
28 Correct 480 ms 33356 KB Output is correct
29 Correct 335 ms 24148 KB Output is correct
30 Correct 537 ms 28288 KB Output is correct
31 Correct 320 ms 13008 KB Output is correct
32 Correct 498 ms 29884 KB Output is correct
33 Correct 507 ms 27308 KB Output is correct
34 Correct 251 ms 24012 KB Output is correct
35 Correct 527 ms 28148 KB Output is correct
36 Correct 362 ms 34252 KB Output is correct