3631: [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
树链剖分+区间修改+单点查询。。。
都是裸的操作。。。只要最后去下重即可。。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdlib> 3 #include<cmath> 4 #include<cstring> 5 #include<cstdio> 6 #include<algorithm> 7 #include<string> 8 #include<map> 9 #include<queue> 10 #include<vector> 11 #include<set> 12 #define inf 1000000000 13 #define maxn 300005 14 #define maxm 300005*2 15 #define eps 1e-10 16 #define ll long long 17 #define for0(i,n) for(int i=0;i<=(n);i++) 18 #define for1(i,n) for(int i=1;i<=(n);i++) 19 #define for2(i,x,y) for(int i=(x);i<=(y);i++) 20 #define for3(i,x,y) for(int i=(x);i>=(y);i--) 21 #define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go) 22 using namespace std; 23 int read() 24 { 25 int x=0,f=1;char ch=getchar(); 26 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 27 while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();} 28 return x*f; 29 } 30 struct edge{ 31 int go,next; 32 }e[maxm]; 33 int head[maxn],w[maxn],top[maxn],fa[maxn],p[maxn],son[maxn],s[maxn],dep[maxn],a[maxn],tot,cnt; 34 struct tree{ 35 int l,r,sum,lazy; 36 }f[maxn*4]; 37 38 void pushup(int i){ 39 f[i].sum=(f[i*2+1].sum+f[i*2].sum); 40 } 41 42 void update(int i,int x) 43 { 44 f[i].sum+=x*(f[i].r-f[i].l+1); 45 f[i].lazy+=x; 46 return; 47 } 48 49 void pushdown(int i){ 50 if(f[i].lazy!=0){ 51 update(i*2,f[i].lazy); 52 update(i*2+1,f[i].lazy); 53 f[i].lazy=0; 54 return; 55 } 56 else return; 57 } 58 59 void build(int i,int left,int right){ 60 int mid=(left+right)/2; 61 f[i].lazy=0;f[i].sum=0; 62 f[i].l=left;f[i].r=right; 63 if(left==right){ 64 return; 65 } 66 build(i*2,left,mid); 67 build(i*2+1,mid+1,right); 68 pushup(i); 69 } 70 71 void add(int i,int left,int right,int v){ 72 int mid=(f[i].l+f[i].r)/2; 73 if(f[i].l==left&&f[i].r==right){ 74 update(i,v); 75 return; 76 } 77 pushdown(i); 78 if(mid>=right)add(i*2,left,right,v); 79 else if(mid<left)add(i*2+1,left,right,v); 80 else add(i*2,left,mid,v),add(i*2+1,mid+1,right,v); 81 pushup(i); 82 } 83 84 int query(int i,int left,int right) { 85 int mid=(f[i].l+f[i].r)/2; 86 if(f[i].l==left&&f[i].r==right) return f[i].sum; 87 pushdown(i); 88 if(mid>=right) return query(i*2,left,right); 89 if(mid<left) return query(i*2+1,left,right); 90 return (query(i*2,left,mid)+query(i*2+1,mid+1,right)); 91 } 92 93 void insert(int u,int v){ 94 e[++tot].go=v;e[tot].next=head[u];head[u]=tot; 95 } 96 void ins(int u,int v){ 97 insert(u,v);insert(v,u); 98 } 99 void dfs(int x){ 100 s[x]=1; 101 for(int y=son[x]=0,i=head[x];i;i=e[i].next){ 102 if(dep[y=e[i].go]==0){ 103 dep[y]=dep[x]+1;fa[y]=x;dfs(y); 104 s[x]+=s[y];if(s[y]>s[son[x]])son[x]=y; 105 } 106 } 107 } 108 void dfs2(int x,int chain){ 109 p[x]=++cnt;top[x]=chain; 110 if(son[x])dfs2(son[x],chain); 111 for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go) 112 if(y!=fa[x]&&y!=son[x])dfs2(y,y); 113 } 114 int solvesum(int x,int y){ 115 int ans=0; 116 while(top[x]!=top[y]){ 117 if(dep[top[x]]<dep[top[y]])swap(x,y); 118 ans+=query(1,p[top[x]],p[x]); 119 x=fa[top[x]]; 120 } 121 if(dep[x]>dep[y])swap(x,y); 122 ans+=query(1,p[x],p[y]); 123 return ans; 124 } 125 void solveadd(int x,int y){ 126 while(top[x]!=top[y]){ 127 if(dep[top[x]]<dep[top[y]])swap(x,y); 128 add(1,p[top[x]],p[x],1); 129 x=fa[top[x]]; 130 } 131 if(dep[x]>dep[y])swap(x,y); 132 add(1,p[x],p[y],1); 133 } 134 int main(){ 135 //freopen("input.txt","r",stdin); 136 //freopen("output.txt","w",stdout); 137 int n=read();dep[1]=1; 138 for1(i,n)a[i]=read(); 139 for1(i,n-1){ 140 int u=read(),v=read(); 141 ins(u,v); 142 } 143 dfs(1);dfs2(1,1); 144 build(1,1,n); 145 for(int i=2;i<=n;i++) 146 solveadd(a[i-1],a[i]); 147 for1(i,n) 148 w[i]=solvesum(i,i); 149 for(int i=2;i<=n;i++)w[a[i]]--; 150 for1(i,n)printf("%d\n",w[i]); 151 return 0; 152 }