QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#397148#8584. 바이러스thangthang#0 0ms0kbC++206.3kb2024-04-23 17:47:192024-07-04 03:36:56

Judging History

你现在查看的是最新测评结果

  • [2024-07-04 03:36:56]
  • 评测
  • 测评结果:0
  • 用时:0ms
  • 内存:0kb
  • [2024-04-23 17:47:19]
  • 提交

answer

// author : HuuHung
// 25.3.2024


#include <bits/stdc++.h>
#define ii pair <int, int>
#define F first
#define S second
#define ll long long
#define lli pair <ll, int>
#define lb long double
#define pb push_back
#define vi vector <int>
#define vll vector <ll>
#define Bit(x, i) ((x) >> (i) & 1)
#define Mask(i) (1ll << (i))
#define All(v) (v).begin(), (v).end()

using namespace std;

void maxzi(auto &a, auto b){
    a = max(a, b);
}

void minzi(auto &a, auto b){
    a = min(a, b);
}

const int N = 1e5 + 5;
const int mod = 1e9 + 7;
const int LG = 20;

void add(auto &a, auto b){
    a += b;
    if (a >= mod) a -= mod;
    if (a < 0) a += mod;
}

auto Pow(auto a, auto b){
    if (b == 0) return 1;
    if (b % 2) return 1ll * a * Pow(a, b - 1) % mod;
    auto c = Pow(a, b / 2);
    return 1ll * c * c % mod;
}

// * end

struct LCA{
    vi st, ed, _lg, high;
    vector <vi> euler, adj;
    int cnt;

    void dfs(int u, int pa){
        ++ cnt;
        st[u] = cnt;
        euler[cnt].pb(u);
        for (int v : adj[u]){
            if (v == pa) continue;
            high[v] = high[u] + 1;
            dfs(v, u);
            euler[++ cnt].pb(u);
        }
        ed[u] = cnt;
    }

    int check(int u, int v) {
        return st[u] <= st[v] && ed[v] <= ed[u];
    }

    int min_by_time(int u, int v) {
        return (st[u] < st[v] ? u : v);
    }

    void add(int u, int v){
        adj[u].pb(v);
        adj[v].pb(u);
    }

    void resize(int n){
        st.resize(n + 3, 0);
        ed.resize(n + 3, 0);
        euler.resize(2 * n + 5);
        adj.resize(n + 3);
        _lg.resize(2 * n + 5);
        high.resize(n + 3, 1);
        for (int i = 0; i <= 2 * n; ++ i) _lg[i] = log2(i);
    }

    void init(int r){
        cnt = 0;
        dfs(r, 0);
        for (int lg = 1; lg < 20; ++lg) {
            for (int i = 1; i + (1 << lg) - 1 <= cnt; ++i)
                euler[i].pb(min_by_time(euler[i][lg - 1], euler[i + (1 << lg - 1)][lg - 1]));
        }
    }

    int get(int u, int v) {
        int L = min(st[u], st[v]);
        int R = max(ed[u], ed[v]);
        int lg = _lg[R - L + 1];
        return min_by_time(euler[L][lg], euler[R - (1 << lg) + 1][lg]);
    }

    int dist(int u, int v){
        int lc = get(u, v);
        return high[u] + high[v] - 2 * high[lc];
    }
} tree;

struct centroid{
    vi sz, used, par, maxdist;
    vector <vi> adj, cur, dhs, Min;

    void resize(int n){
        sz.resize(n + 3, 0);
        used.resize(n + 3, 0);
        adj.resize(n + 3);
        cur.resize(n + 3);
        par.resize(n + 3, -1);
        maxdist.resize(n + 3, 0);
        dhs.resize(n + 3);
        Min.resize(n + 3);
    }

    void add(int u, int v){
        adj[u].pb(v);
        adj[v].pb(u);
    }

    int dfs(int u, int p = -1){
        sz[u] = 1;
        for (int v : adj[u]){
            if (v == p || used[v]) continue;
            sz[u] += dfs(v, u);
        }

        return sz[u];
    }

    int get_cen(int m, int u, int p = -1){
        for (int v : adj[u]){
            if (v != p && !used[v] && 2 * sz[v] > m)
                return get_cen(m, v, u);
        }

        return u;
    }

    int cen(int u){
        u = get_cen(dfs(u), u);
        used[u] = 1;
        for (int v : adj[u]){
            if (!used[v]) cur[u].pb(cen(v));
        }
        return u;
    }

    map <ii, int> mp;
    int tot = 0;
    vi ask;
    vector <ii> status;

    void build(int u, vi &C){
        dhs[u].pb(u);
        for (int v : cur[u]){
            if (v == par[u]) continue;
            par[v] = u;
            build(v, C);
            for (int k : dhs[v]){
                dhs[u].pb(k);
                maxzi(maxdist[u], tree.dist(u, k));
            }
        }
        Min[u].resize(maxdist[u] + 1);
        for (int k : dhs[u]) minzi(Min[u][tree.dist(u, k)], C[k]);
        for (int i = 0; i <= maxdist[u]; ++ i){
            if (i > 0) minzi(Min[u][i], Min[u][i - 1]);
            mp[ii(u, i)] = tot;
            ++ tot;
            status.pb(ii(u, i));
            if (i > 0) ask.pb(1);
            else ask.pb(0);
        }
    }
} ce;

struct Dij{
    vector <vector <ii>> adj;
    vll dist;
    const ll inf = 1e18;
    int n;

    Dij(int _n){
        n = _n;
        adj.resize(n + 3);
        dist.resize(n + 3, inf);
    }

    void add(int u, int v, int w){
        adj[u].pb(ii(v, w));
        //adj[v].pb(ii(u, w));
    }

    priority_queue <lli> qu;

    void process(){
        while (!qu.empty()){
            auto [du, u] = qu.top();
            du = -du;
            qu.pop();
            if (du != dist[u]) continue;
            for (auto [v, dv] : adj[u]){
                if (dist[v] > du + dv){
                    dist[v] = du + dv;
                    qu.push(lli(-dist[v], v));
                }
            }
        }
    }

    void build(vi &P, vi &D){
        for (int i = 0; i < ce.tot; ++ i){
            if (ce.ask[i]) {
                auto [u, dep] = ce.status[i - 1];
                add(i, i - 1, 0);
                add(i - 1, i, ce.Min[u][dep] - ce.Min[u][dep + 1]);
            }
        }
        for (int i = 0; i < P.size(); ++ i){
            int u = P[i];
            while (u > -1){
                int re = D[i] - tree.dist(P[i], u);
                if (re >= 0){
                    int d = ce.mp[ii(u, re)];
                    add(i, d, 0);
                    add(d, i, ce.Min[u][re]);
                }
                u = ce.par[u];
            }
        }

        dist[ce.tot] = 0;
        qu.push(lli(0, ce.tot));
        process();
    }
};

vll find_spread(int N, int M, vi A, vi B, vi P, vi D, vi C){
    tree.resize(N);
    ce.resize(N);
    for (int i = 0; i < N - 1; ++ i){
        tree.add(A[i], B[i]);
        ce.add(A[i], B[i]);
    }
    tree.init(0);
    ce.cen(0);
    ce.build(0, C);
    Dij ac(ce.tot + M);
    ac.build(P, D);
    vll ans;
    for (int i = 0; i < M; ++ i) ans.pb(ac.dist[ce.tot + i]);
    return ans;
}

//void solve(){
//
//}
//
//
//int main(){
//    ios_base::sync_with_stdio(0);
//    cin.tie(0);
//    cout.tie(0);
//    int t; cin >> t;
//    while (t --) solve();
//
//    return 0;
//}






Details

Tip: Click on the bar to expand more detailed information

Subtask #1:

score: 0
Runtime Error

Test #1:

score: 0
Runtime Error

input:

8 5
0 1
1 2
2 3
3 4
4 5
5 6
6 7
2 2
5 0
7 0
1 1
4 1
40 5 5 16 32 8 1 10

output:

Unauthorized output

result:


Subtask #2:

score: 0
Skipped

Dependency #1:

0%

Subtask #3:

score: 0
Skipped

Dependency #2:

0%

Subtask #4:

score: 0
Runtime Error

Test #34:

score: 0
Runtime Error

input:

8 5
0 1
1 2
2 3
3 4
4 5
3 6
3 7
2 2
5 0
7 0
1 1
4 1
40 5 5 16 32 8 1 10

output:

Unauthorized output

result:


Subtask #5:

score: 0
Skipped

Dependency #4:

0%

Subtask #6:

score: 0
Skipped

Dependency #1:

0%