题目描述
松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的。天哪,他居然真的住在”树“上。
松鼠想邀请****前来参观,并且还指定一份参观指南,他希望**能够按照他的指南顺序,先去a1,再去a2,......,最后到an,去参观新家。可是这样会导致**重复走很多房间,懒惰的**不停地推辞。可是松鼠告诉他,每走到一个房间,他就可以从房间拿一块糖果吃。
**是个馋家伙,立马就答应了。现在松鼠希望知道为了保证**有糖果吃,他需要在每一个房间各放至少多少个糖果。
因为松鼠参观指南上的最后一个房间an是餐厅,餐厅里他准备了丰盛的大餐,所以当**在参观的最后到达餐厅时就不需要再拿糖果吃了。
输入输出格式
输入格式:
第一行一个整数n,表示房间个数第二行n个整数,依次描述a1-an接下来n-1行,每行两个整数x,y,表示标号x和y的两个房间之间有树枝相连。
输出格式:
一共n行,第i行输出标号为i的房间至少需要放多少个糖果,才能让**有糖果吃。
输入输出样例
说明
2<= n <=300000
因为这个题,只要最后面查询,所以可以用树状数组的区间修改来做,所以,上代码:
#include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cstdio> #include<ctime> #include<cmath> #include<queue> #include<stack> #include<map> #include<set> #define ll(x) (x*2) #define rr(x) (x*2+1) #define lol long long using namespace std; const int maxn=300008; lol read() { char ch=getchar();lol f=1,w=0; while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch<='9'&&ch>='0'){w=w*10+ch-'0';ch=getchar();} return f*w; } struct sj{ lol to; lol next; }a[maxn*2]; lol head[maxn],size; lol vis[maxn],js[maxn],n; lol top[maxn],son[maxn],num[maxn]; lol id[maxn],dep[maxn],fa[maxn]; lol c[maxn],nat[maxn]; void add(lol x,lol y) { a[++size].to=y; a[size].next=head[x]; head[x]=size; } void dfs(lol rt,lol pre,lol deep) { dep[rt]=deep; num[rt]=1; fa[rt]=pre; for(int i=head[rt];i;i=a[i].next) { lol tt=a[i].to; if(tt!=fa[rt]) { dfs(tt,rt,deep+1); num[rt]+=num[tt]; if(num[tt]>num[son[rt]]) son[rt]=tt; } } } int dfn; void dfs_find(lol rt,lol zu) { dfn++; top[rt]=zu; id[rt]=dfn; if(son[rt]!=-1) dfs_find(son[rt],zu); for(int i=head[rt];i;i=a[i].next) { lol tt=a[i].to; if(tt!=son[rt]&&tt!=fa[rt]) { dfs_find(tt,tt); } } return; } int lowbit(int x) { return x&(-x); } void insert(int x,int z) { for(int i=x;i<=n;i+=lowbit(i)) {if(i==0)break;c[i]+=z;} } int check(int x) { int sum=0; for(int i=x;i>=1;i-=lowbit(i)) { sum+=c[i]; } return sum; } void change(int s,int t) //change 还有一点*问题 没有剪掉起点 { while(top[s]!=top[t]) { if(dep[top[s]]<dep[top[t]]) swap(s,t); insert(id[top[s]],1); insert(id[s]+1,-1); s=fa[top[s]]; } if(id[s]>id[t]) swap(s,t); insert(id[s],1); insert(id[t]+1,-1); return; } int main() { memset(son,-1,sizeof(son)); memset(top,-1,sizeof(top)); n=read(); for(int i=1;i<=n;i++) vis[i]=read(); for(int i=1;i<n;i++) { lol x,y; x=read(); y=read(); add(x,y); add(y,x); } dfs(1,0,1); dfs_find(1,1); js[vis[1]]+=1; js[vis[n]]-=1; for(int i=1;i<n;i++) { change(vis[i],vis[i+1]); js[vis[i]]-=1; } for(int i=1;i<=n;i++) { lol ss; ss=check(id[i]); ss+=js[i]; cout<<ss<<endl; } return 0; }