首页 > 代码库 > BZOJ3631: [JLOI2014]松鼠的新家

BZOJ3631: [JLOI2014]松鼠的新家

传送门

树上的差分优化,很简单的一道题,应该属于NOIP2015TGD2T3的子问题。

 

//BZOJ 3631//by Cydiater//2016.10.25#include <iostream>#include <cstdlib>#include <cstdio>#include <cmath>#include <ctime>#include <cstring>#include <string>#include <algorithm>#include <queue>#include <map>#include <bitset>#include <iomanip>using namespace std;#define ll long long#define up(i,j,n)		for(int i=j;i<=n;i++)#define down(i,j,n)		for(int i=j;i>=n;i--)const int MAXN=6e5+5;const int oo=0x3f3f3f3f;inline int read(){	char ch=getchar();int x=0,f=1;	while(ch>‘9‘||ch<‘0‘){if(ch==‘-‘)f=-1;ch=getchar();}	while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}	return x*f;}int N,a[MAXN],LINK[MAXN],lable[MAXN],len=0,fa[MAXN][25],dep[MAXN];struct edge{	int y,next;}e[MAXN];namespace solution{	inline void insert(int x,int y){e[++len].next=LINK[x];LINK[x]=len;e[len].y=y;}	void init(){		N=read();		up(i,1,N)a[i]=read();		up(i,1,N-1){			int x=read(),y=read();			insert(x,y);			insert(y,x);		}	}	void dfs(int node,int deep,int father){		fa[node][0]=father;dep[node]=deep;		for(int i=LINK[node];i;i=e[i].next)if(e[i].y!=father)			dfs(e[i].y,deep+1,node);	}	void get_ancestor(){		up(i,1,20)up(node,1,N)if(fa[node][i-1]!=0)			fa[node][i]=fa[fa[node][i-1]][i-1];	}	int LCA(int x,int y){		if(x==y)		return x;		if(dep[x]<dep[y])swap(x,y);		down(i,20,0)if(dep[x]-(1<<i)>=dep[y])x=fa[x][i];		if(x==y)		return x;		down(i,20,0)if(fa[x][i]!=0&&fa[x][i]!=fa[y][i]){			x=fa[x][i];y=fa[y][i];		}		return fa[x][0];	}	void re_dfs(int node){		for(int i=LINK[node];i;i=e[i].next)if(e[i].y!=fa[node][0]){			re_dfs(e[i].y);			lable[node]+=lable[e[i].y];		}	}	void slove(){		dfs(1,0,0);		get_ancestor();		up(i,1,N-1){			int x=a[i],y=a[i+1],lca=LCA(x,y);			lable[x]++;lable[y]++;lable[fa[lca][0]]--;lable[lca]--;		}		re_dfs(1);		up(i,2,N)lable[a[i]]--;	}	void output(){		up(i,1,N)printf("%d\n",lable[i]);	}}int main(){	//freopen("input.in","r",stdin);	using namespace solution;	init();	slove();	output();	return 0;}

BZOJ3631: [JLOI2014]松鼠的新家