码迷,mamicode.com
首页 > 其他好文 > 详细

[HEOI 2014]大工程

时间:2018-02-21 10:39:52      阅读:178      评论:0      收藏:0      [点我收藏+]

标签:code   script   down   utc   online   表示   pac   pre   next   

Description

题库链接

给你一个 \(n\) 个节点的树, \(q\) 组询问,每次给出 \(k\) 个关键点,询问这 \(k\) 个关键点两两间路径长度和,长度最值。

\(1\leq n\leq 1000000, 1\leq q\leq 50000,\sum k\leq 2n\)

Solution

建完虚树后,直接简单的树形 \(DP\) ,开四个辅助数组, \(size,sum,maxn,minn\) 表示虚树中以它为根的子树中所有关键点的个数,到它的路径长度和,长度最值。

再一顿乱搞就好了。

Code

//It is made by Awson on 2018.2.21
#include <bits/stdc++.h>
#define LL long long
#define dob complex<double>
#define Abs(a) ((a) < 0 ? (-(a)) : (a))
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))
#define writeln(x) (write(x), putchar('\n'))
#define lowbit(x) ((x)&(-(x)))
using namespace std;
const int N = 1000000;
const int INF = ~0u>>1;
void read(int &x) {
    char ch; bool flag = 0;
    for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
    for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
    x *= 1-2*flag;
}
void print(LL x) {if (x > 9) print(x/10); putchar(x%10+48); }
void write(LL x) {if (x < 0) putchar('-'); print(Abs(x)); }

int n, lim, fa[N+5][25], dep[N+5], dfn[N+5], times, u, v;
LL maxans, minans, sumans, minn[N+5], maxn[N+5], sum[N+5], size[N+5];
int lst[N+5], flag[N+5], k, t, S[N+5], top;
struct graph {
    struct tt {int to, next; }edge[(N<<1)+5];
    int path[N+5], top;
    void add(int u, int v) {edge[++top].to = v, edge[top].next = path[u], path[u] = top; }
    void dfs1(int o, int depth) {
    dep[o] = depth, dfn[o] = ++times;
    for (int i = 1; i <= lim; i++) fa[o][i] = fa[fa[o][i-1]][i-1];
    for (int i = path[o]; i; i = edge[i].next)
        if (dfn[edge[i].to] == 0) fa[edge[i].to][0] = o, dfs1(edge[i].to, depth+1);
    }
    void dfs2(int o) {
    minn[o] = INF, maxn[o] = -INF, sum[o] = 0, size[o] = 0;
    if (flag[o]) minn[o] = maxn[o] = 0, size[o] = 1;
    for (int &i = path[o]; i; i = edge[i].next) {
        dfs2(edge[i].to);
        sumans += size[o]*(sum[edge[i].to]+(dep[edge[i].to]-dep[o])*size[edge[i].to])+sum[o]*size[edge[i].to];
        sum[o] += sum[edge[i].to]+size[edge[i].to]*(dep[edge[i].to]-dep[o]), size[o] += size[edge[i].to];
        minans = Min(minans, minn[o]+minn[edge[i].to]+dep[edge[i].to]-dep[o]), minn[o] = Min(minn[o], minn[edge[i].to]+dep[edge[i].to]-dep[o]);
        maxans = Max(maxans, maxn[o]+maxn[edge[i].to]+dep[edge[i].to]-dep[o]), maxn[o] = Max(maxn[o], maxn[edge[i].to]+dep[edge[i].to]-dep[o]);
    }
    }
}g1, g2;
bool comp(const int &a, const int &b) {return dfn[a] < dfn[b]; }
int get_lca(int u, int v) {
    if (dep[u] < dep[v]) Swap(u, v);
    for (int i = lim; i >= 0; i--) if (dep[fa[u][i]] >= dep[v]) u = fa[u][i];
    if (u == v) return u;
    for (int i = lim; i >= 0; i--) if (fa[u][i] != fa[v][i]) u = fa[u][i], v = fa[v][i];
    return fa[u][0];
}

void work() {
    read(n); lim = log(n)/log(2);
    for (int i = 1; i < n; i++) read(u), read(v), g1.add(u, v), g1.add(v, u);
    g1.dfs1(1, 1); read(t);
    while (t--) {
    read(k); top = g2.top = 0; maxans = -INF, minans = INF, sumans = 0;
    for (int i = 1; i <= k; i++) read(lst[i]), flag[lst[i]] = 1;
    sort(lst+1, lst+1+k, comp); S[++top] = lst[1];
    for (int i = 2; i <= k; i++) {
        int lca = get_lca(lst[i], S[top]);
        while (dfn[lca] < dfn[S[top]]) {
        if (dfn[lca] >= dfn[S[top-1]]) {
            g2.add(lca, S[top]); --top;
            if (S[top] != lca) S[++top] = lca;
            break;
        }
        g2.add(S[top-1], S[top]), --top;
        }
        S[++top] = lst[i];
    }
    while (top > 1) g2.add(S[top-1], S[top]), --top;
    g2.dfs2(S[1]);
    write(sumans), putchar(' '), write(minans), putchar(' '), writeln(maxans);
    for (int i = 1; i <= k; i++) flag[lst[i]] = 0;
    }
}
int main() {
    work(); return 0;
}

[HEOI 2014]大工程

标签:code   script   down   utc   online   表示   pac   pre   next   

原文地址:https://www.cnblogs.com/NaVi-Awson/p/8456238.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!