树剖+差分爆零求调
查看原帖
树剖+差分爆零求调
716721
leo12334楼主2024/7/5 08:55

样例过了但是爆零,思路和第六篇题解一致

#include<bits/stdc++.h>
using namespace std;
#define N 500860
#define ll long long
#define in read() 
ll a[N],b[N],bb[N];
int fa[N],n,m,dfn[N],cnt,x,y,z,v,l,r,mid,root,op,deep[N],head[N],tp[N],size[N],son[N],tt;
struct node{
	int next,to;
}e[N*2];
void add(int x,int y){
	e[++cnt].next=head[x];
	e[cnt].to=y;
	head[x]=cnt;
}
ll read(){ 
	ll x=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){
		if(c=='-')f=-1;c=getchar();
	} 
	while(c<='9'&&c>='0'){
		x=(x>>3)+(x>>1)+c-'0';
		c=getchar();
	}
	return x*f;
}
void dfs1(int x){
	size[x]=1;
	int big=0;
	for(int i=head[x];i;i=e[i].next){
		int y=e[i].to;
		if(y==fa[x])continue;
		fa[y]=x;deep[y]=deep[x]+1;
		dfs1(y);
		size[x]+=size[y];
		if(size[y]>big)big=size[y],son[x]=y;
	}
}
void dfs2(int x,int tou){
	dfn[x]=++tt;
	tp[x]=tou;
	if(son[x]) dfs2(son[x],tou);
	for(int i=head[x];i;i=e[i].next){
		int y=e[i].to;
		if(y!=fa[x]&&y!=son[x]){
			dfs2(y,y);
		}
	}
}
void lca(int x,int y){
	while(tp[x]!=tp[y]){
		if(deep[tp[x]]>deep[tp[y]])swap(x,y);
		bb[dfn[tp[y]]]++;bb[dfn[y]+1]--;
		y=fa[tp[y]];	
	}
	if(deep[x]>deep[y])swap(x,y);
	bb[dfn[x]]++;bb[dfn[y]+1]--;
} 
int main(){
	n=in;
	for(int i=1;i<=n;i++) a[i]=in;
	for(int i=1;i<n;i++){
		x=in,y=in;
		add(x,y);add(y,x);
	}
	tp[1]=1;
	dfs1(1);
	dfs2(1,1);
	bb[2]--;
	for(int i=1;i<n;i++)lca(a[i],a[i+1]);
	for(int i=1;i<=n;i++)b[i]=b[i-1]+bb[i];
	for(int i=1;i<=n;i++)cout<<b[dfn[i]]<<endl;
	return 0; 
} 
2024/7/5 08:55
加载中...