2020 wannafly лагеря day1 E дерево и путь - разница дерева

Тема ссылки: точка I ах ╭ (╯ ^ ╰) ╮

С учетом эффекта:

    Внедренное дерево, найти ряд весов и пути
    весов пути определяются следующим образом:
    от начала до конца кратчайшего пути, число ребер вверх × × число ребер идти вниз

Проблемно-разрешающие идеи:

    Для одного пути ( в , v ) (u,v) , установить длину L е N только , L с LCA к в в расстояние Икс Икс
     N s L с знак равно Икс * ( L е N - Икс ) ans_ {LCA} = х * (LEN - х) , установите L с LCA направлением в в сына направления s N сын
     N s s N знак равно ( Икс - 1 ) * ( L е N - Икс + 1 ) ans_ {его} = (х - 1) * (LEN - х + 1)
     N s L с - N s s N знак равно L е N - 2 Икс + 1 LCA ans_ {} - {ans_ его} = Len - 2х + 1

    для L е N + 1 Только + 1 этой части, право эквивалентно всех точек на этом пути + знак равно L е N + 1 + = Только + 1
    Для - 2 Икс -2x В данном разделе также можно рассматривать как разность:
    Точка в в из Икс Икс является 1 1 , чей отец 2 2 ,затем 4... 4 ...
    То есть разность арифметической обработки последовательности мысли

Ядро: разница дерева обработки арифметической последовательности

#include<bits/stdc++.h>
#define rint register int
#define x first
#define y second
#define deb(x) cerr<<#x<<" = "<<(x)<<'\n';
using namespace std;
typedef long long ll;
using pii = pair <ll,ll>;
const int maxn = 3e5 + 5;
int n, m, f[maxn][35];
ll ans[maxn], dep[maxn];
vector <int> g[maxn];
pii a[maxn];

void dfs1(int u, int fa, int de) {
	dep[u] = de, f[u][0] = fa;
	for(int i=1; i<=30; i++)
		f[u][i] = f[f[u][i-1]][i-1];
	for(auto v : g[u]) {
		if(v == fa) continue;
		dfs1(v, u, de+1);
	}
}

int LCA(int x, int y){
	if(dep[x]<dep[y]) swap(x, y);
	for(int i=30; i>=0; i--)
		if(dep[f[x][i]]>=dep[y])
			x = f[x][i];
	if(x == y) return x;
	for(int i=30; i>=0; i--)
		if(f[x][i] ^ f[y][i])
			x=f[x][i], y=f[y][i];
	return f[x][0];
}

void dfs2(int u, int fa) {
	for(auto v : g[u]) {
		if(v == fa) continue;
		dfs2(v, u);
		a[u].x += a[v].x;
		a[u].y += a[v].y;
	}
	a[u].x -= 2ll * a[u].y;
}

void dfs3(int u, int fa, ll num) {
	ans[u] = num;
	for(auto v : g[u]) {
		if(v == fa) continue;
		dfs3(v, u, num - a[v].x);
	}
}

int main() {
	scanf("%d%d", &n, &m);
	for(int i=1, u, v; i<n; i++) {
		scanf("%d%d", &u, &v);
		g[u].push_back(v);
		g[v].push_back(u);
	}
	dfs1(1, 0, 1);
	while(m--) {
		ll u, v, lca, len;
		scanf("%lld%lld", &u, &v);
		lca = LCA(u, v);
		len = dep[u] + dep[v] - 2ll * dep[lca];
		a[u].x += len + 1, a[u].y += 1;
		a[lca].x -= len + 1 - 2ll * (dep[u] - dep[lca]), a[lca].y -= 1;

		a[v].x += len + 1, a[v].y += 1;
		a[lca].x -= len + 1 - 2ll * (dep[v] - dep[lca]), a[lca].y -= 1;
		ans[1] += 1ll * (dep[u] - dep[lca]) * (dep[v] - dep[lca]);
	}
	dfs2(1, 0);
	dfs3(1, 0, ans[1]);
	for(int i=1; i<=n; i++) printf("%lld\n", ans[i]);
}
Опубликовано 221 оригинальные статьи · вона похвала 220 · просмотров 20000 +

рекомендация

отblog.csdn.net/Scar_Halo/article/details/104095579
рекомендация