zoukankan      html  css  js  c++  java
  • bzoj5457 城市

    一棵树,每个点有一个民族,和一个人数,求每个子树里最多的民族及其人数,如果一样,输出编号最小的

    $n leq 500000$

    sol:

    卡莫队的毒瘤题,需要 dsu on tree

    大概就是 dfs 顺便维护一个数组叫“当前答案”,每次先把轻儿子加进来,再把重儿子加进来,然后把轻儿子删掉,重儿子继承这个“当前答案”数组

    然后由于两点间最多有 log 条重链,复杂度很对劲

    #include <bits/stdc++.h>
    #define LL long long
    #define rep(i, s, t) for (register int i = (s), i##end = (t); i <= i##end; ++i)
    #define dwn(i, s, t) for (register int i = (s), i##end = (t); i >= i##end; --i)
    using namespace std;
    inline int read() {
        int x = 0, f = 1; char ch;
        for (ch = getchar(); !isdigit(ch); ch = getchar()) if (ch == '-') f = -f;
        for (; isdigit(ch); ch = getchar()) x = 10 * x + ch - '0';
        return x * f;
    }
    const int maxn = 400010;
    int n, m, a[maxn], b[maxn];
    int first[maxn], to[maxn << 1], nx[maxn << 1], pnt;
    inline void add(int u, int v) {
        to[++pnt] = v;
        nx[pnt] = first[u];
        first[u] = pnt;
    }
    int fa[maxn], mxs[maxn], size[maxn];
    inline void dfs1(int x) {
        size[x] = 1;
        for(int i=first[x];i;i=nx[i]) {
            if(to[i] == fa[x]) continue;
            fa[to[i]] = x;
            dfs1(to[i]); size[x] += size[to[i]];
            if(size[to[i]] > size[mxs[x]]) mxs[x] = to[i];
        }
    }
    int cnt[maxn], now;
    int ans[maxn], ansn[maxn];
    inline void cal(int x, int opt) {
        cnt[b[x]] += opt * a[x];
        if((cnt[b[x]] > cnt[now]) || ((cnt[b[x]] == cnt[now]) && (b[x] < now) && (opt == 1))) now = b[x];
        for(int i=first[x];i;i=nx[i])
            if(to[i] != fa[x]) cal(to[i], opt);
    }
    inline void dfs(int x, int opt) {
        for(int i=first[x];i;i=nx[i])
            if(to[i] != fa[x] && to[i] != mxs[x]) dfs(to[i], 0);
        if(mxs[x]) dfs(mxs[x], 1);
        for(int i=first[x];i;i=nx[i])
            if(to[i] != fa[x] && to[i] != mxs[x]) cal(to[i], 1);
        cnt[b[x]] += a[x];
        if((cnt[b[x]] > cnt[now]) || ((cnt[b[x]] == cnt[now]) && (b[x] < now))) now = b[x];
        ans[x] = now; ansn[x] = cnt[now];
        if(!opt) now = 0, cal(x, -1);
    }
    int main() {
        n = read(), m = read();
        rep(i, 2, n) {
            int u = read(), v = read();
            add(u, v); add(v, u);
        } dfs1(1); cnt[0] = -1;
        rep(i, 1, n) b[i] = read(), a[i] = read();
        dfs(1, 1);
        rep(i, 1, n) printf("%d %d
    ", ans[i], ansn[i]);
    }
    View Code
  • 相关阅读:
    learning scala view collection
    scala
    learning scala dependency injection
    learning scala implicit class
    learning scala type alise
    learning scala PartialFunction
    learning scala Function Recursive Tail Call
    learning scala Function Composition andThen
    System.Threading.Interlocked.CompareChange使用
    System.Threading.Monitor的使用
  • 原文地址:https://www.cnblogs.com/Kong-Ruo/p/10515600.html
Copyright © 2011-2022 走看看