LOJ #2236. 「JLOI2014」松鼠的新家【樹上差分】
阿新 • • 發佈:2018-12-13
板子題:
#include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define ll long long #define rep(i,x,y) for(ll i=(x);i<=(y);i++) #define repl(i,x,y) for(ll i=(x);i<(y);i++) #define repd(i,x,y) for(ll i=(x);i>=(y);i--) using namespace std; const ll N=3e5+5; const ll Inf=1e18; ll n,m,pos[N],sum[N],dep[N],fa[N][20]; ll cnt,to[N<<1],nxt[N<<1],head[N]; inline ll read() { ll x=0;char ch=getchar();bool f=0; while(ch>'9'||ch<'0'){if(ch=='-')f=1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} return f?-x:x; } void getans(ll x) { for(ll i=head[x];i;i=nxt[i]) if(to[i]!=fa[x][0]) getans(to[i]),sum[x]+=sum[to[i]]; } void ins(ll x,ll y) { to[++cnt]=y;nxt[cnt]=head[x];head[x]=cnt; } void dfs(ll x) { dep[x]=dep[fa[x][0]]+1; rep(i,1,19) fa[x][i]=fa[fa[x][i-1]][i-1]; for(ll i=head[x];i;i=nxt[i]) if(to[i]!=fa[x][0]) fa[to[i]][0]=x,dfs(to[i]); } ll lca(ll x,ll y) { if(dep[x]<dep[y]) swap(x,y);ll dlt=dep[x]-dep[y]; rep(i,0,19) if(dlt&(1<<i)) x=fa[x][i]; if(x==y) return y; repd(i,19,0) if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i]; return fa[x][0]; } int main() { n=read(); rep(i,1,n) pos[i]=read(); repl(i,1,n) { ll x=read(),y=read(); ins(x,y),ins(y,x); } dfs(1); repl(i,1,n) { ll _lca=lca(pos[i],pos[i+1]); sum[pos[i]]++,sum[pos[i+1]]++; sum[_lca]--,sum[fa[_lca][0]]--; } getans(1); rep(i,2,n) sum[pos[i]]--; rep(i,1,n) printf("%lld\n",sum[i]); return 0; }