时间限制 : - MS   空间限制 : - KB 
评测说明 : 2s,256m
问题描述

蒜头君有一棵有根树,树的每一边都有边权,蒜头君想知道任意两点间最短距离之和为多少。 另外,由于各种原因,蒜头君的树的边的边权会发生若干次改变,蒜头君想让你告诉他,每一 次改变后,任意两点间最短距离之和为多少?

输入格式

输出格式

r

样例输入

4
1 1
1 1
1 1
1
2 2

样例输出

9
12

【题目分析】
算法 1
每次 O(N2) 查询每两对点的距离,时间复杂度 O(N2M),期望得分 30 分。
算法 2
考虑每条边会在答案中被计算几次,假设删除一条边后所得到的连通分量的大小为 a 和 b,
则 这条边会被统计 a*b 次,可以用一遍 DFS 得到每个点及其子节点的总数,然后可以得
到 a 和 b,对于每个询问都做一遍 DFS。时间复杂度 O(N ∗ M),期望得分 70 分。
算法 3
对于任意一条边 i, 设该边长度为 L[i], 连的儿子节点为 x。
size[x]为 x 为根的子树中节点的总数。 那么 i 号边被公交线路经过的次数为 size[x]*(n-size[x])
i 号边对答案的贡献为 TotLen+=L[i]* size[x]*(n-size[x])
对于每个询问,只考虑修改每一条边会变成什么样,则可以 O(1) 处理每一个询问,时间复
杂度 O(N + M),期望得分 100 分。

【参考代码】
 #include<cstdio>
#include<cctype>
#define ll long long
#define maxn 100003
using namespace std;
int n, m, tot;
int Last[maxn], Fa[maxn], Size[maxn], Num[maxn];
ll ans;
ll F[maxn];
char buf[ << ], *p1 = buf, *p2 = buf, obuf[ << ], *O = obuf;
struct node {
int End, Next, Len;
}Edge[maxn << ];
namespace Ironclad_Programming {
#define R register int
#define For(i, s, n) for (R i = s; i <= n; ++ i)
#define Getch() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1 ++)
inline int read() {
int x = , f = ;
char ch = Getch();
while(!isdigit(ch)){if (ch == '-')f = -; ch = Getch();}
while(isdigit(ch))x = x * + (ch ^ ), ch = Getch();
return x * f;
}
inline void Add(int x, int y, int z) {
Edge[++ tot].End = y;
Edge[tot].Len = z;
Edge[tot].Next = Last[x];
Last[x] = tot;
}
void ini() {
n = read();
For (i, , n) {
int x, y;
x = read(), y = read();
Add(x, i, y);
Add(i, x, y);
Fa[i] = x;
Num[i] = tot;
}
}
namespace solve {
void DFS(int x) {
++ Size[x];
for (R i = Last[x]; i; i = Edge[i].Next) {
int y = Edge[i].End;
if (y ^ Fa[x]) {
DFS(y);
ans += 1LL * Edge[i].Len * F[y];
Size[x] += Size[y];
}
}
F[x] = 1LL * Size[x] * (n - Size[x]);
}
void Del_Back() {
m = read();
For (i, , m) {
int x, y;
x = read(), y = read();;
ans += 1LL * (y - Edge[Num[x]].Len) * F[x];
Edge[Num[x]].Len = y;
printf("%lld\n", ans);
}
}
void executive() {
DFS();
printf("%lld\n", ans);
Del_Back();
}
}
void Main() {
ini();
solve::executive();
}
#undef R
#undef For
#undef Getch
}
int main() {
Ironclad_Programming::Main();
return ;
}

B 蒜头君的树的更多相关文章

  1. 计蒜客模拟赛D1T2 蒜头君的树:树上节点之间最短距离和

    题目链接:https://nanti.jisuanke.com/t/16446 题意: 给你一棵有n个节点的树以及每条边的长度,输出树上节点之间的最短距离和.然后进行m次操作,每次操作更改一条边的长度 ...

  2. noip模拟赛 蒜头君的树

    分析:这道题问的是树上整体的答案,当然要从整体上去考虑. 一条边对答案的贡献是这条边一端连接的点的个数*另一端连接的点的个数*边权,可以用一次dfs来统计答案,之后每次更改操作在原答案的基础上增减就好 ...

  3. 计蒜客D2T2 蒜头君的排序(动态维护树状数组)

    蒜头君的排序(sort) 2000ms 262144K 蒜头君是一个爱思考的好孩子,这一天他学习了冒泡排序,于是他就想,把一个乱序排列通过冒泡排序排至升序需要多少次交换,这当然难不倒他,于是他想来点刺 ...

  4. 计蒜客模拟赛D2T3 蒜头君救人:用bfs转移状压dp

    题目链接:https://nanti.jisuanke.com/t/16444 题意: 蒜头君是一个乐于助人的好孩子,这天他所在的乡村发生了洪水,有多名村民被困于孤岛上,于是蒜头君决定去背他们离开困境 ...

  5. 计蒜客模拟赛D1T3 蒜头君的坐骑:用dfs转移dp

    题目链接:https://nanti.jisuanke.com/t/16447 题意: 蒜头君有一只坐骑,人马. 一天,蒜头君骑着他的坐骑走上了一片n*m的大荒野,一开始时,蒜头君在(1,1)点,他要 ...

  6. gcd前缀和-蒜头君的数轴

    题目: 今天蒜头君拿到了一个数轴,上边有 n个点,但是蒜头君嫌这根数轴不够优美,想要通过加一些点让它变优美,所谓优美是指考虑相邻两个点的距离,最多只有一对点的距离与其它的不同. 蒜头君想知道,他最少需 ...

  7. 蒜头君学英语--set()练习

    题目描述 蒜头君快要考托福了,这几天,蒜头君每天早上都起来记英语单词.花椰妹时不时地来考一考蒜头君:花椰妹会询问蒜头君一个单词,如果蒜头君背过这个单词,蒜头君会告诉花椰妹这个单词的意思,不然蒜头君会跟 ...

  8. 计蒜客习题:蒜头君的积木 (状压DP 枚举子集)

    问题描述 蒜头君酷爱搭积木,他用积木搭了 n 辆重量为 wi的小车和一艘最大载重量为 W 的小船,他想用这艘小船将 n 辆小车运输过河.每次小船运载的小车重量不能超过 W.另外,小船在运载小车时,每辆 ...

  9. 计蒜客 蒜头君回家(有条件的BFS)

    蒜头君要回家,但是他家的钥匙在他的朋友花椰妹手里,他要先从花椰妹手里取得钥匙才能回到家.花椰妹告诉他:“你家的钥匙被我复制了很多个,分别放在不同的地方.” 蒜头君希望能尽快回到家中,他需要首先取得任意 ...

随机推荐

  1. JZOJ 5236. 【NOIP2017模拟8.7A组】利普希茨

    5236. [NOIP2017模拟8.7A组]利普希茨 (File IO): input:lipschitz.in output:lipschitz.out Time Limits: 1000 ms ...

  2. 【WPF学习】第五十七章 使用代码创建故事板

    在“[WPF学习]第五十章 故事板”中讨论了如何使用代码创建简单动画,以及如何使用XAML标记构建更复杂的故事板——具有多个动画以及播放控制功能.但有时采用更复杂的故事板例程,并在代码中实现全部复杂功 ...

  3. CMAKE交叉编译快速入门

    cmake 工具 cmake 使用非常简单,最常用的用法是 cmake . 在当前目录执行cmake 官方帮助 -D <var>:<type>=<value> -D ...

  4. 前端Tips#6 - 在 async iterator 上使用 for-await-of 语法糖

    视频讲解 前往原文 前端Tips 专栏#6,点击观看 文字讲解 本期主要是讲解如何使用 for-await-of 语法糖进行异步操作迭代,让组织异步操作的代码更加简洁易读. 1.场景简述 以下代码中的 ...

  5. node打开本地应用程序

    1.打开浏览器 最简单的方法: const cp = require('child_process') cp.exec('start http://127.0.0.1:8889/'); // 自动打开 ...

  6. Thread同步

    今天本人给大家讲解一下多线程的线程同步,如有不对的或者讲的不好的可以多多提出,我会进行相应的更改,先提前感谢提出意见的各位了!!! 开始说线程同步前先来个小案例: 案例启:所有的类都在Demo01中, ...

  7. 一文掌握Redis的三种集群方案

    在开发测试环境中,我们一般搭建Redis的单实例来应对开发测试需求,但是在生产环境,如果对可用性.可靠性要求较高,则需要引入Redis的集群方案.虽然现在各大云平台有提供缓存服务可以直接使用,但了解一 ...

  8. Python数据基本类型3

    -*- coding:utf-8 -*-字典 键值对数据 dict dic = {'键':'值'}存储数据 字典的查找快一些不可哈希的,就是可变的数据 可变的数据不能哈希 不可变的数据能哈希 pyth ...

  9. windows下安装spark-python

    首先需要安装Java 下载安装并配置Spark 从官方网站Download Apache Spark™下载相应版本的spark,因为spark是基于hadoop的,需要下载对应版本的hadoop才行, ...

  10. 使用GUI工具Portainer.io管控Docker容器

    背景 5年前容器技术扑面而来,如今已经成为面向云原生开发的基础架构,基于微服务的设计需要部署大量容器,同时强调了友好快速的管理容器. 是时候推荐一个轮子Portainer.io:提供GUI界面的容器管 ...