http://codeforces.com/contest/348/problem/B

题意:给一棵树,每个叶子结点有w[i]个苹果,每个子树的苹果数量为该子树所有叶子结点苹果数量之和,要使得每个结点的各个子树苹果数量相等,求至少需要拿走的苹果数量。

思路:一开始以为只要使得所有子树之和相同就行了。

 void dfs(int u, int fa) {
int num = , mi = INF;
for(int i = head[u]; ~i; i = edge[i].nxt) {
int v = edge[i].v; if(v == fa) continue;
dfs(v, u);
sz[u] += sz[v]; num++; mi = mi > sz[v] ? sz[v] : mi;
}
//printf("%d : %lld - %d - %d\n", u, sz[u], mi, num);
ans += sz[u] - mi * num;
sz[u] = mi * num + w[u];
}

后来看错误的样例,是没理解好题意。

例如这组样例:

10
0 9 5 0 0 0 0 0 9 7
7 5
8 1
1 5
4 3
2 4
4 7
7 9
10 6
6 8

红色的为正确的,蓝色为之前想错的。

题解:“对于一棵以u为根的子树,如果要减少若干个苹果,那么需要从u的每棵子树中取走等量的苹果,这个过程会递归下去直到叶子,
考虑对每个节点维护两个信息,mx[u]表示u子树中最多的苹果数,cnt[u]表示u子树中苹果数必须是cnt[u]的倍数,
如果u是叶子,那么有mx[u]=a[u],cnt[u]=1,否则有cnt[u]=lcm(cnt[v]),这里v是u的儿子,mx[u]则是不超过min(mx[v])的最大的cnt[u]的倍数,
最后结果就是mx[1],复杂度O(nlogA),这个logA是gcd的复杂度。”

真的好厉害 = =

 #include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define N 100010
#define INF 0x3f3f3f3f
struct Edge {
int v, nxt;
} edge[N*];
LL w[N], ans, mx[N], cnt[N];
int head[N], tot;
void Add(int u, int v) {
edge[tot] = (Edge) { v, head[u] }; head[u] = tot++;
edge[tot] = (Edge) { u, head[v] }; head[v] = tot++;
} LL gcd(LL a, LL b) { return b ? gcd(b, a % b) : a; } LL lcm(LL a, LL b) { return a / gcd(a, b) * b; } void dfs(int u, int fa) {
int num = ;
for(int i = head[u]; ~i; i = edge[i].nxt) {
int v = edge[i].v; if(v == fa) continue;
dfs(v, u);
if(!num) mx[u] = mx[v], cnt[u] = cnt[v];
else {
if(cnt[u] < 1e14) cnt[u] = lcm(cnt[u], cnt[v]);
mx[u] = min(mx[u], mx[v]) / cnt[u] * cnt[u]; // mx 必须是cnt[u]的倍数
}
num++;
}
if(!num) mx[u] = w[u], cnt[u] = ;
else {
mx[u] *= num;
if(cnt[u] < 1e14) cnt[u] *= num;
}
// printf("%d : %lld - %lld\n", u, mx[u], cnt[u]);
} int main() {
int n; scanf("%d", &n); LL ans = ;
for(int i = ; i <= n; i++) scanf("%lld", &w[i]), ans += w[i];
memset(head, -, sizeof(head)); tot = ;
for(int i = ; i < n; i++) {
int u, v; scanf("%d%d", &u, &v); Add(u, v);
}
dfs(, -);
cout << ans - mx[] << endl;
return ;
}

Codeforces 348B:Apple Tree(DFS+LCM+思维)的更多相关文章

  1. Codeforces 348B - Apple Tree

    348B - Apple Tree 我们设最后答案为 x , 我们我们就能用x表示出所有节点下面的苹果个数, 然后用叶子节点求lcm, 取最大的可行解. #include<bits/stdc++ ...

  2. POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和)

    POJ.3321 Apple Tree ( DFS序 线段树 单点更新 区间求和) 题意分析 卡卡屋前有一株苹果树,每年秋天,树上长了许多苹果.卡卡很喜欢苹果.树上有N个节点,卡卡给他们编号1到N,根 ...

  3. poj 3321 Apple Tree dfs序+线段树

    Apple Tree Time Limit: 2000MS   Memory Limit: 65536K       Description There is an apple tree outsid ...

  4. [poj3321]Apple Tree(dfs序+树状数组)

    Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 26762   Accepted: 7947 Descr ...

  5. POJ3321 - Apple Tree DFS序 + 线段树或树状数组

    Apple Tree:http://poj.org/problem?id=3321 题意: 告诉你一棵树,每棵树开始每个点上都有一个苹果,有两种操作,一种是计算以x为根的树上有几个苹果,一种是转换x这 ...

  6. POJ 3321 Apple Tree dfs+二叉索引树

    题目:http://poj.org/problem?id=3321 动态更新某个元素,并且求和,显然是二叉索引树,但是节点的标号不连续,二叉索引树必须是连续的,所以需要转化成连续的,多叉树的形状已经建 ...

  7. POJ 3321 Apple Tree (DFS + 树状数组)

    题意: 一棵苹果树有N个分叉,编号1---N(根的编号为1),每个分叉只能有一颗苹果或者没有苹果. 现在有两种操作: 1.某个分叉上的苹果从有变无或者从无边有. 2.需要统计以某个分叉为根节点时,它的 ...

  8. POJ 3321 Apple Tree DFS序+fenwick

    题目大意:有一颗长满苹果的苹果树,有两个操作. 1.询问以一个点为根的子树中有多少个苹果. 2.看看一个点有没有苹果,假设没有苹果.那么那里就立即长出一个苹果(= =!):否则就把那个苹果摘下来. 思 ...

  9. POJ 3321 Apple Tree DFS序 + 树状数组

    多次修改一棵树节点的值,或者询问当前这个节点的子树所有节点权值总和. 首先预处理出DFS序L[i]和R[i] 把问题转化为区间查询总和问题.单点修改,区间查询,树状数组即可. 注意修改的时候也要按照d ...

随机推荐

  1. 好用的Markdown 编辑器及工具

    Markdown 是 2004 年由 John Gruberis 设计和开发的纯文本格式的语法,所以通过同一个名字它可以使用工具来转换成 HTML.readme 文件,在线论坛编写消息和快速创建富文本 ...

  2. 最简单的IdentityServer实现——Api

    1.创建项目并添加引用 创建ASP.NET Core Web API项目IdentityServer.EasyDemo.Api   1   2 引用IdentityServer4.AccessToke ...

  3. C#开发奇技淫巧一:调试windows系统服务

    原文:C#开发奇技淫巧一:调试windows系统服务 windows系统服务不能直接运行,只能在安装完服务之后启动.暂停.继续.停止服务,导致服务的调试不能使用一般的断点调试. 要调试系统服务,可以采 ...

  4. JS 两种数组类型

    <!DOCTYPE html><html lang="en" xmlns="http://www.w3.org/1999/xhtml"> ...

  5. jquery 显示和隐藏的三种方式

     <!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml"><head>    & ...

  6. ASP.NET获取客户端、服务器端基础信息

    1. 在ASP.NET中专用属性: 获取服务器电脑名:Page.Server.ManchineName 获取用户信息:Page.User 获取客户端电脑名:Page.Request.UserHostN ...

  7. JS浏览器滚轮事件实现横向滚动照片展

    if(window.attachEvent){ ///*IE8注册事件*/ this.oc.attachEvent('onmousewheel',function(e) { //函数体 }); } e ...

  8. Dlib 19.4(算法,压缩,图像处理,机器学习,Meta编程,网络,HTTP服务器)

    Algorithms API Wrappers Bayesian Nets Compression Containers Graph Tools Image Processing Linear Alg ...

  9. Firemonkey实现Mac OS程序中内嵌浏览器的功能(自己动手翻译,调用苹果提供的webkit框架)

    XE系列虽然可以跨平台,但是在跨平台的道路上只是走了一小半的路,很多平台下的接口都没实现彻底,所以为了某些功能,还必须自己去摸索. 想实现程序中可以内嵌浏览器的功能,但是Firemonkey还没有对应 ...

  10. [書訊]《.NET 依賴注入》 (2014-12-08 更新)

    书 名:.NET 依赖注入 页 数:235 格 式:PDF.EPUB.MOBI难易度:中阶至进阶出版日期:2014 年 12 月 8 日ISBN:9789574320684 简介 本书内容是关于 .N ...