noip模拟赛 蒜头君的树
2024-09-30 22:43:20
分析:这道题问的是树上整体的答案,当然要从整体上去考虑.
一条边对答案的贡献是这条边一端连接的点的个数*另一端连接的点的个数*边权,可以用一次dfs来统计答案,之后每次更改操作在原答案的基础上增减就好了.
千万不要傻傻地去求LCA......事实证明只有10分.问的是任意两点最短距离之和,树上两个点的最短路径只有一条,所以才要去考虑每条边的贡献的.
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; const int maxn = ; long long n, head[maxn], nextt[maxn * ], tot = , to[maxn * ], w[maxn * ], num[maxn], fa[maxn], d[maxn], m;
long long ans; void add(long long x, long long y, long long z)
{
to[tot] = y;
w[tot] = z;
nextt[tot] = head[x];
head[x] = tot++;
} void dfs(long long u, long long fa)
{
for (int i = head[u]; i; i = nextt[i])
{
int v = to[i];
if (v != fa)
{
dfs(v, u);
num[u] += num[v];
ans += w[i] * num[v] * (n - num[v]);
}
}
num[u]++;
} int main()
{
scanf("%lld", &n);
for (int i = ; i <= n; i++)
{
long long x, y;
scanf("%lld%lld", &x, &y);
fa[i] = x;
d[i] = y;
add(x, i, y);
}
dfs(, fa[]);
printf("%lld\n", ans);
scanf("%lld", &m);
for (int i = ; i <= m; i++)
{
long long a, b;
scanf("%lld%lld", &a, &b);
ans += num[a] * (n - num[a]) * (b - d[a]);
printf("%lld\n", ans);
d[a] = b;
} return ;
}
最新文章
- Android动画效果之Property Animation进阶(属性动画)
- iOS中的一些细节
- nginx服务器的网站权限问题
- VSS错误自动修复
- 附录二 C语言标准库
- timersmanager 解析
- Share_memory
- IO_REMOVE_LOCK使用方法小结(转载加改正)
- Oracle- UPDATE FROM讲解
- 切换samba用户
- HDU 3966 dfs序+LCA+树状数组
- angular指令之complie和link不得不说的故事
- iOS UICollectionView(转三)
- python写zip破解器
- Subversion配置
- Java中的匿名内部类及内部类的二三事
- c#生成连续单号
- @staticmethod和classmethod
- python - isinstance/issubclass 函数
- hdu4812 逆元+树分治