树链剖分 + 树上差分 10pts 求助
查看原帖
树链剖分 + 树上差分 10pts 求助
544458
WAI_kycm楼主2023/5/19 19:13

就只过样例和第五个测试点

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6;
int n;
struct Tree{
	int to, next;
}e[maxn];
int len, head[maxn];
void Insert(int u, int v){
	e[++len].to = v; e[len].next = head[u]; head[u] = len;
}
int f[maxn], siz[maxn], top[maxn], deep[maxn], cnt[maxn], son[maxn];
void dfs1(int u){
	deep[u] = deep[f[u]] + 1; siz[u] = 1;
	for(int i = head[u]; i; i = e[i].next){
		int v = e[i].to;
		if(v == f[u]) continue;
		f[v] = u;
		dfs1(v);
		siz[u] += siz[v];
		if(!son[u] or siz[v] > siz[son[u]]) son[u] = v;
	}
}
void dfs2(int u, int fa){
	top[u] = fa;
	if( son[u]) dfs2(son[u], fa);
	for(int i = head[u]; i; i = e[i].next){
		int v = e[i].to;
		if(v != son[u] and v != f[u]) dfs2(v, v);
	}
}
int Find(int u, int v){
	while(top[u] != top[v]){
		if(deep[top[u]] >= deep[top[v]]) u = f[top[u]];
		else v = f[top[v]];
	}
	return deep[u] < deep[v] ? u : v;
}
void dfs3(int u){
	for(int i = head[u]; i; i = e[i].next){
		int v = e[i].to;
		if(v == f[u]) continue;
		dfs3(v);
		cnt[u] += cnt[v];
	}
}
int x[maxn];
void Solve(){
	cin>>n;
	for(int i = 1; i <= n; ++i) cin>>x[i];
	for(int i = 1; i < n; ++i){
		int u, v; cin>>u>>v;
		Insert(u, v); Insert(v, u);
	}
	dfs1(1); dfs2(1, 1);
	for(int i = 1; i < n; ++i){
		int u = x[i], v = x[i + 1], lca = Find(u, v);
		cnt[u]++; cnt[v]++; cnt[lca]--; cnt[f[lca]]--;
	}
	dfs3(1);
	for(int i = 2; i <= n; ++i) cnt[i]--;
	for(int i = 1; i <= n; ++i) cout<<cnt[i]<<endl;
}
int main(){
	Solve();
	return 0;
}
2023/5/19 19:13
加载中...