题目大意

给你一个树,每个节点上有有一个部落,以及部落的人数,要你求出每个节点的子树里面人数最多的部落是哪一个(人数相同部落编号最小的)。

思路

全网第一篇分治题解

考虑树的dfs序,然后分治处理,每层只处理跨过mid的区间,然后就完了。

时间复杂度\(O(nlogn)\),但常数比树上启发式合并小。

Code

#include <cstdio>
#include <cstdlib>
#include <cstring>
#define Re register
#define ll long long
bool st;
const int N = 400000 + 5;
inline int read() {
int ret = 0, f = 0; char ch;
do {
ch = getchar();
if (ch == '-') f = 1;
} while (ch < '0' || ch > '9');
do {
ret = (ret << 3) + (ret << 1) + ch - '0';
ch = getchar();
} while (ch <= '9' && ch >= '0');
return f ? - ret : ret;
} inline void hand_in() {
freopen("endless.in", "r", stdin);
freopen("endless.out", "w", stdout);
} struct Graph {
int to[N << 1], nxt[N << 1], head[N], cnt;
inline void add(int x, int y) {
++cnt;
to[cnt] = y, nxt[cnt] = head[x], head[x] = cnt;
}
}G;
int n, m, a[N], b[N];
struct Node { int val, id; }ans[N];
int dfn[N], sz[N], tot, id[N];
inline void dfs(int u, int fa) {
dfn[u] = ++ tot;
id[tot] = u;
sz[u] = 1;
for (Re int i = G.head[u];i;i = G.nxt[i]) {
int v = G.to[i];
if (v == fa) continue;
dfs(v, u);
sz[u] += sz[v];
}
} int c[N], sta[N], top;
inline void cal(int l, int r) {
if (l >= r) {
if (sz[id[l]] == 1) ans[id[l]].id = a[id[l]], ans[id[l]].val = b[id[l]];
return;
}
int mid = (l + r) >> 1;
cal(l, mid), cal(mid + 1, r);
top = 0;
int mx = 0, ids, p = mid + 1;
for (int i = mid;i >= l; --i) {
int u = id[i];
sta[++top] = a[u];
c[a[u]] += b[u];
if (c[a[u]] > mx || (c[a[u]] == mx && ids > a[u])) mx = c[a[u]], ids = a[u];
int ed = i + sz[u] - 1;
if (ed <= mid || ed > r) continue;
while (p <= ed) {
int v = id[p];
c[a[v]] += b[v];
sta[++top] = a[v];
if (c[a[v]] > mx || (c[a[v]] == mx && ids > a[v])) mx = c[a[v]], ids = a[v];
p ++;
}
ans[u].val = mx, ans[u].id = ids;
}
for (Re int i = 1;i <= top; ++i) c[sta[i]] = 0;
} bool ed;
int main() {
hand_in();
n = read(), m = read();
for (Re int i = 1, u, v;i < n; ++i) {
u = read(), v = read();
G.add(u, v), G.add(v, u);
}
for (Re int i = 1;i <= n; ++i) {
a[i] = read(), b[i] = read();
}
dfs(1, 0), cal(1, n);
for (int i = 1;i <= n; ++i) {
printf("%d %d\n", ans[i].id, ans[i].val);
}
return 0;
}

最新文章

  1. Linux2.6.11版本:classic RCU的实现
  2. JVM之数据类型
  3. 直接修改.NET程序集 LLBL Gen 2.x-4.x 许可授权方法研究
  4. ehcache整合spring本地接口方式
  5. svn上传文件
  6. PyQt4学习笔记2:事件和信号
  7. jtemplate使用笔记
  8. Deflater与Inflater的压缩与解压缩
  9. Fluentd: Open Source Log Management
  10. 201521123002《Java程序设计》第10周学习总结
  11. 如何去掉ul标签的多余空白或多余大距离?
  12. [快速幂][NOIP2012]转圈游戏
  13. SATA工作模式咋选?揭秘AHCI和IDE区别(全文)
  14. Codeforces Round #323 (Div. 2) E - Superior Periodic Subarrays
  15. js图片加载效果(延迟加载+瀑布流加载)
  16. 高速入门:十分钟学会Python
  17. PHP.ini中配置屏蔽错误信息显示和保存错误日志
  18. Mabatis(2) 全局配置文件
  19. 探讨android更新UI的几种方法(转)
  20. Python基础--字典:当索引不好用时

热门文章

  1. 机器学习之决策树原理和sklearn实践
  2. UltraISO 下载
  3. [后渗透]获取到 Meterpreter 之后的操作
  4. R 目录及文件操作
  5. Shell 逐行读取文件的4中方法
  6. js函数如何传递多个参数
  7. 【Gamma】 Scrum Meeting 1
  8. 深度排序模型概述(一)Wide&amp;Deep/xDeepFM
  9. TypeScript in 5 minutes
  10. ubuntu下Vim安装失败