题目描述
松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的。天哪,他居然真的住在”树“上。
松鼠想邀请****前来参观,并且还指定一份参观指南,他希望**能够按照他的指南顺序,先去a1,再去a2,......,最后到an,去参观新家。可是这样会导致**重复走很多房间,懒惰的**不听地推辞。可是松鼠告诉他,每走到一个房间,他就可以从房间拿一块糖果吃。
**是个馋家伙,立马就答应了。现在松鼠希望知道为了保证**有糖果吃,他需要在每一个房间各放至少多少个糖果。
因为松鼠参观指南上的最后一个房间an是餐厅,餐厅里他准备了丰盛的大餐,所以当**在参观的最后到达餐厅时就不需要再拿糖果吃了。
输入输出格式
输入格式:
第一行一个整数n,表示房间个数第二行n个整数,依次描述a1-an接下来n-1行,每行两个整数x,y,表示标号x和y的两个房间之间有树枝相连。
输出格式:
一共n行,第i行输出标号为i的房间至少需要放多少个糖果,才能让**有糖果吃。
输入输出样例
输入样例#1:
5 1 4 5 3 2 1 2 2 4 2 3 4 5
输出样例#1:
1 2 1 2 1
说明
2<= n <=300000
题解:
分明就是一道树链剖分模板题
可是我还是写+调花了1个*时(55555……)
好伤心啊,看来这些模板该再练练了,千万不能考试时又花这么长时间
代码:

1 #include<cstdio> 2 #include<iostream> 3 #include<string.h> 4 using namespace std; 5 6 const int MAXN = 300005; 7 struct node{ 8 int v; 9 node *next; 10 }pool[2*MAXN],*h[MAXN]; 11 int cnt; 12 int fa[MAXN],dep[MAXN],son[MAXN],sonnum[MAXN],vis[MAXN]; 13 int a[MAXN]; 14 15 void addedge(int u,int v){ 16 node *p=&pool[++cnt],*q=&pool[++cnt]; 17 p->v=v;p->next=h[u];h[u]=p; 18 q->v=u;q->next=h[v];h[v]=q; 19 } 20 21 void dfs(int u){ 22 int v; 23 int maxson,maxnum=0; 24 sonnum[u]=1; 25 vis[u]=1; 26 for(node *p=h[u];p;p=p->next) 27 if(!vis[v=p->v]){ 28 dep[v]=dep[u]+1; 29 fa[v]=u; 30 dfs(v); 31 sonnum[u]+=sonnum[v]; 32 if(sonnum[v]>maxnum) maxnum=sonnum[v],maxson=v; 33 } 34 if(maxnum!=0) son[u]=maxson; 35 else son[u]=-1; 36 } 37 38 int w[MAXN],rk[MAXN],t,top[MAXN]; 39 void dfs2(int u){ 40 int v; 41 vis[u]=1; 42 v=son[u]; 43 if(v!=-1){ 44 top[v]=top[u]; 45 rk[v]=++t; 46 w[t]=v; 47 dfs2(v); 48 } 49 for(node *p=h[u];p;p=p->next) 50 if(!vis[v=p->v] && v!=son[u]){ 51 top[v]=v; 52 rk[v]=++t; 53 w[t]=v; 54 dfs2(v); 55 } 56 } 57 58 struct tree{ 59 int v,lazy,l,r; 60 tree *parent,*ch[2]; 61 }d[MAXN*8],*root; 62 int cnt1; 63 void Build_Tree(tree *p,int l,int r){ 64 p->l=l;p->r=r; 65 d[t].v=0;d[t].lazy=0; 66 if(l==r) return; 67 int mid=(l+r)/2; 68 p->ch[0]=&d[++cnt1];p->ch[1]=&d[++cnt1]; 69 Build_Tree(p->ch[0],l,mid); 70 Build_Tree(p->ch[1],mid+1,r); 71 } 72 void change(tree *p,int l,int r,int c){ 73 if(p->l==l && p->r==r){ 74 p->lazy+=c; 75 return; 76 } 77 if(p->lazy){ 78 p->ch[0]->lazy+=p->lazy; 79 p->ch[1]->lazy+=p->lazy; 80 p->lazy=0; 81 } 82 if(l>=p->ch[1]->l) change(p->ch[1],l,r,c); 83 else if(r<=p->ch[0]->r) change(p->ch[0],l,r,c); 84 else{ 85 change(p->ch[0],l,p->ch[0]->r,c); 86 change(p->ch[1],p->ch[1]->l,r,c); 87 } 88 } 89 int query(tree *p,int l,int r){ 90 if(p->l==l && p->r==r){ 91 return p->lazy; 92 } 93 if(p->lazy){ 94 p->ch[0]->lazy+=p->lazy; 95 p->ch[1]->lazy+=p->lazy; 96 p->lazy=0; 97 } 98 if(l>=p->ch[1]->l) return query(p->ch[1],l,r); 99 else if(r<=p->ch[0]->r) return query(p->ch[0],l,r); 100 else{ 101 return query(p->ch[0],l,p->ch[0]->r)+query(p->ch[1],p->ch[1]->l,r); 102 } 103 } 104 105 void lca(int x,int y){ 106 int f1=top[x],f2=top[y]; 107 while(f1!=f2){ 108 if(dep[f1]<dep[f2]) swap(f1,f2),swap(x,y); 109 change(root,rk[f1],rk[x],1); 110 x=fa[f1];f1=top[x]; 111 } 112 if(dep[x]>dep[y]) swap(x,y); 113 change(root,rk[x],rk[y],1); 114 } 115 int ans[MAXN]; 116 117 int main() 118 { 119 int i,j,n,x,y; 120 scanf("%d",&n); 121 for(i=1;i<=n;i++) scanf("%d",&a[i]); 122 for(i=1;i<n;i++){ 123 scanf("%d%d",&x,&y); 124 addedge(x,y); 125 } 126 127 root=&d[++cnt1]; 128 dep[1]=1; 129 dfs(1); 130 memset(vis,0,sizeof(vis)); 131 top[1]=1;rk[1]=1;t=1;w[1]=1; 132 dfs2(1); 133 Build_Tree(root,1,t); 134 135 for(i=1;i<n;i++) lca(a[i],a[i+1]); 136 137 for(i=1;i<=n;i++){ 138 x=query(root,i,i); 139 if(w[i]!=a[1]) x--; 140 ans[w[i]]=x; 141 } 142 for(i=1;i<=n;i++) printf("%d ",ans[i]); 143 144 return 0; 145 }