BZOJ3631 [JLOI2014]松鼠的新家
Description
松 鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的。天哪,他 居然真的住在“树”上。松鼠想邀请****前来参观,并且还指定一份参观指南,他希望**能够按照他的指南顺序,先去a1,再去a2,……,最后到an, 去参观新家。
可是这样会导致**重复走很多房间,懒惰的**不听地推辞。可是松鼠告诉他,每走到一个房间,他就可以从房间拿一块糖果吃。**是个馋家伙,立马就答应了。
现在松鼠希望知道为了保证**有糖果吃,他需要在每一个房间各放至少多少个糖果。因为松鼠参观指南上的最后一个房间an是餐厅,餐厅里他准备了丰盛的大餐,所以当**在参观的最后到达餐厅时就不需要再拿糖果吃了。
Input
第一行一个整数n,表示房间个数
第二行n个整数,依次描述a1-an
接下来n-1行,每行两个整数x,y,表示标号x和y的两个房间之间有树枝相连。
Output
一共n行,第i行输出标号为i的房间至少需要放多少个糖果,才能让**有糖果吃。
Sample Input
5
1 4 5 3 2
1 2
2 4
2 3
4 5
1 4 5 3 2
1 2
2 4
2 3
4 5
Sample Output
1
2
1
2
1
2
1
2
1
HINT
2<= n <=300000
正解:树链剖分+线段树
解题报告:
链剖裸题。
1 //It is made by jump~ 2 #include <iostream> 3 #include <cstdlib> 4 #include <cstring> 5 #include <cstdio> 6 #include <cmath> 7 #include <algorithm> 8 #include <ctime> 9 #include <vector> 10 #include <queue> 11 #include <map> 12 #include <set> 13 #ifdef WIN32 14 #define OT "%I64d" 15 #else 16 #define OT "%lld" 17 #endif 18 using namespace std; 19 typedef long long LL; 20 const int MAXN = 300011; 21 const int MAXM = 600011; 22 int n,ecnt; 23 int first[MAXN],next[MAXM],to[MAXM]; 24 int top[MAXN],son[MAXN],deep[MAXN],father[MAXN],id[MAXN],size[MAXN],pre[MAXN]; 25 int que[MAXN],ql,qr,ans[MAXN]; 26 27 struct node{ 28 int add; 29 }a[MAXN*4]; 30 31 inline int getint() 32 { 33 int w=0,q=0; 34 char c=getchar(); 35 while((c<'0' || c>'9') && c!='-') c=getchar(); 36 if (c=='-') q=1, c=getchar(); 37 while (c>='0' && c<='9') w=w*10+c-'0', c=getchar(); 38 return q ? -w : w; 39 } 40 41 inline void dfs1(int x,int fa){ 42 father[x]=fa; size[x]=1; 43 for(int i=first[x];i;i=next[i]) { 44 int v=to[i]; if(v==fa) continue; 45 deep[v]=deep[x]+1; dfs1(v,x); 46 size[x]+=size[v]; if(size[v]>size[son[x]]) son[x]=v; 47 } 48 } 49 50 inline void dfs2(int x,int fa){ 51 id[x]=++ecnt; pre[ecnt]=x; if(son[x]) top[son[x]]=top[x],dfs2(son[x],x); 52 for(int i=first[x];i;i=next[i]) { 53 int v=to[i]; if(v==fa || v==son[x]) continue; 54 top[v]=v; dfs2(v,x); 55 } 56 } 57 58 inline void update(int root,int l,int r){ 59 if(ql<=l && r<=qr) { a[root].add++; return ; } 60 int mid=(l+r)/2; int lc=root*2,rc=lc+1; 61 if(ql<=mid) update(lc,l,mid); if(qr>mid) update(rc,mid+1,r); 62 } 63 64 inline void lca(int x,int y){ 65 int f1=top[x],f2=top[y]; 66 while(f1!=f2) { 67 if(deep[f1]<deep[f2]) swap(f1,f2),swap(x,y); 68 ql=id[f1]; qr=id[x]; update(1,1,n); 69 x=father[f1]; f1=top[x]; 70 } 71 if(deep[x]<deep[y]) swap(x,y); 72 ql=id[y]; qr=id[x]; update(1,1,n); 73 } 74 75 inline void pushdown(int root,int l,int r){ 76 if(l==r) { ans[pre[l]]=a[root].add; return ; } 77 int mid=(l+r)/2; int lc=root*2,rc=lc+1; 78 a[lc].add+=a[root].add; a[rc].add+=a[root].add; 79 pushdown(lc,l,mid); pushdown(rc,mid+1,r); 80 } 81 82 inline void work(){ 83 n=getint(); for(int i=1;i<=n;i++) que[i]=getint(); 84 int x,y; 85 for(int i=1;i<n;i++) { 86 x=getint(); y=getint(); 87 next[++ecnt]=first[x]; first[x]=ecnt; to[ecnt]=y; 88 next[++ecnt]=first[y]; first[y]=ecnt; to[ecnt]=x; 89 } 90 deep[1]=0; dfs1(1,0); 91 ecnt=0; top[1]=1; dfs2(1,0); 92 for(int i=2;i<=n;i++) { lca(que[i-1],que[i]); } 93 pushdown(1,1,n); for(int i=2;i<=n;i++) ans[que[i]]--; 94 for(int i=1;i<=n;i++) printf("%d\n",ans[i]); 95 } 96 97 int main() 98 { 99 work(); 100 return 0; 101 }
本文作者:ljh2000
作者博客:http://www.cnblogs.com/ljh2000-jump/
转载请注明出处,侵权必究,保留最终解释权!