• 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
  • 相关阅读:
    layui的模块化和非模块化使用
    layui实现类似于bootstrap的模态框功能
    ajax下载文件
    【IDEA】IDEA中maven项目pom.xml依赖不生效解决
    主-主数据库系统架构
    MyEclipse x.x各版本终极优化配置指南
    Cactus入门
    有史以来最出彩的编程语言名字
    安卓开发20:动画之Animation 详细使用-主要通过java代码实现动画效果
    第一次讲课总结
  • 原文地址:https://www.cnblogs.com/Kong-Ruo/p/10515600.html
Copyright © 2020-2023  润新知