2020 CCPC-Wannfaly-da1 树与路径
回想Day1真是可怕,场场都是倒数的。。。。(金牌爷太强了)
题目如下(吉老师出的题)
传送门:https://ac.nowcoder.com/acm/contest/3979/E

个人感觉这题不是很难那种(不过比赛时候确实没写出来)因为确实没有练习过树上差分,不知道树上前缀和有什么用。。。

公式就是这样了,吉老师写的更简便,(但是看不懂)
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
const int maxn = 3e5 + 100;
ll dep[maxn];
int f[maxn][30];
ll dp[maxn];//答案
ll list[maxn];//前缀
ll cnt[maxn];
ll ans[maxn];
vector<int>G[maxn];
void insert(int be, int en) {
G[be].push_back(en);
}
int dfs(int x, int fa) {
dep[x] = dep[fa] + 1;
for (int i = 0; i < G[x].size(); i++) {
int p = G[x][i];
if (p == fa) continue;
f[p][0] = x;
dfs(p, x);
}
return 0;
}
int LCA(int x, int y) {
if (dep[x] > dep[y]) swap(x, y);
for (int i = 22; i >= 0; i--) {
if (dep[x] <= dep[f[y][i]]) {
y = f[y][i];
}
}
if (x == y) return x;
for (int i = 22; i >= 0; i--) {
if (f[x][i] != f[y][i]) {
x = f[x][i];
y = f[y][i];
}
}
return f[x][0];
}
struct node {
int be, en;
ll len;
}que[maxn];
int dfs1(int x, int fa) {
for (int i = 0; i < G[x].size(); i++) {
int p = G[x][i];
if (p == fa) continue;
dfs1(p, x);
ans[x] += ans[p];
cnt[x] += cnt[p];
}
list[x] = cnt[x];
return 0;
}
int dfs2(int x, int fa) {
for (int i = 0; i < G[x].size(); i++) {
int p = G[x][i];
if (p == fa) continue;
dfs2(p, x);
ans[x] += ans[p];
list[x] += list[p];
}
return 0;
}
int dfs3(int x, int fa) {
for (int i = 0; i < G[x].size(); i++) {
int p = G[x][i];
if (p == fa) continue;
dp[p] = dp[x] + 2 * list[p] - ans[p] - cnt[p];
dfs3(p, x);
}
return 0;
}
int main() {
int n, m;
int be, en;
scanf("%d %d", &n, &m);
for (int i = 1; i < n; i++) {
scanf("%d %d", &be, &en);
insert(be, en);
insert(en, be);
}
dfs(1, 0);
for (int k = 1; k < 25; k++) {
for (int i = 1; i <= n; i++) {
f[i][k] = f[f[i][k - 1]][k - 1];
}
}
ll cns = 0;
for (int i = 0; i < m; i++) {
scanf("%d %d", &be, &en);
int root = LCA(be, en);
cnt[be]++;
cnt[en]++;
cnt[root] -= 2;
ll d = dep[be] + dep[en] - 2 * dep[root];
que[i].be = be;
que[i].en = en;
que[i].len = d;
dp[1] += 1LL*(dep[be] - dep[root])*(dep[en] - dep[root]);
}
dfs1(1, -1);
ll len;
for (int i = 0; i < m; i++) {
be = que[i].be;
en = que[i].en;
len = que[i].len;
int root = LCA(be, en);
ans[be] += len;
ans[en] += len;
ans[root] -= 2 * len;
list[root] -= (dep[be] - dep[root]);
list[root] -= (dep[en] - dep[root]);
}
dfs2(1, -1);
dfs3(1, -1);
for (int i = 1; i <= n; i++) {
printf("%lld\n", dp[i]);
}
return 0;
}
寻找真正的热爱

浙公网安备 33010602011771号