BZOJ3631: [JLOI2014]松鼠的新家
2014-12-04 13:14
302 查看
3631: [JLOI2014]松鼠的新家
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 495 Solved: 248
[Submit][Status]
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
51 4 5 3 2
1 2
2 4
2 3
4 5
Sample Output
12
1
2
1
HINT
2<= n <=300000题解:
为什么省选会出裸树链剖分。。。
现在看起来连线段树也不用打了,类似于 雨天的尾巴 打标记就可以了233
线段树会T掉一些分?
代码:
#include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #include<algorithm> #include<iostream> #include<vector> #include<map> #include<set> #include<queue> #include<string> #define inf 1000000000 #define maxn 500000+5 #define maxm 2500000+5 #define eps 1e-10 #define ll long long #define pa pair<int,int> #define for0(i,n) for(int i=0;i<=(n);i++) #define for1(i,n) for(int i=1;i<=(n);i++) #define for2(i,x,y) for(int i=(x);i<=(y);i++) #define for3(i,x,y) for(int i=(x);i>=(y);i--) #define mod 1000000007 using namespace std; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=10*x+ch-'0';ch=getchar();} return x*f; } int n,m,q,tot,sum,head[maxn],top[maxn],id[maxn],son[maxn],dep[maxn],s[maxn],fa[maxn],ans[maxn]; int a[maxn],b[maxn][2],c[maxn]; struct edge{int go,next;}e[2*maxn]; inline void insert(int x,int y) { e[++tot]=(edge){y,head[x]};head[x]=tot; e[++tot]=(edge){x,head[y]};head[y]=tot; } inline void dfs(int x) { s[x]=1; for(int i=head[x],y;i;i=e[i].next) if(!dep[y=e[i].go]) { dep[y]=dep[x]+1;fa[y]=x; dfs(y); s[x]+=s[y]; if(s[y]>s[son[x]])son[x]=y; } } inline void dfs2(int x,int chain) { id[x]=++m;top[x]=chain; if(son[x])dfs2(son[x],chain); for(int i=head[x];i;i=e[i].next)if(e[i].go!=son[x]&&e[i].go!=fa[x])dfs2(e[i].go,e[i].go); } inline void dfs3(int x) { sum+=b[x][0]; ans[x]=sum; sum-=b[x][1]; if(son[x])dfs3(son[x]); } int main() { freopen("input.txt","r",stdin); freopen("output.txt","w",stdout); n=read(); for1(i,n)a[i]=read(); for2(i,2,n)c[a[i]]++; for1(i,n-1)insert(read(),read()); dep[1]=1;dfs(1);dfs2(1,1); for1(i,n-1) { int x=a[i],y=a[i+1]; while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]])swap(x,y); b[top[x]][0]++; b[x][1]++; x=fa[top[x]]; } if(dep[x]>dep[y])swap(x,y); b[x][0]++; b[y][1]++; } for1(i,n)if(top[i]==i)dfs3(i); for1(i,n)printf("%d\n",ans[i]-c[i]); return 0; }
View Code
相关文章推荐
- BZOJ 3631 JLOI2014 松鼠的新家 树链剖分/LCA
- [bzoj 3631--JLOI2014]松鼠的新家
- 【bzoj 3631】[JLOI2014]松鼠的新家(树链剖分)
- [bzoj3631][JLOI2014]松鼠的新家 树上差分
- [BZOJ3631][JLOI2014]松鼠的新家(链剖)
- bzoj 3631: [JLOI2014]松鼠的新家
- Bzoj 3631: [JLOI2014]松鼠的新家(树链剖分+线段树)
- 【BZOJ3631】[JLOI2014]松鼠的新家
- [JLOI2014][BZOJ3631] 松鼠的新家|树上倍增LCA|差分
- BZOJ 3631 [JLOI2014]松鼠的新家 tarjanlca
- 洛谷 P3258 BZOJ 3631 [JLOI2014]松鼠的新家
- 【BZOJ3631】【JLOI2014】松鼠的新家
- BZOJ 3631: [JLOI2014]松鼠的新家
- BZOJ 3631 [JLOI2014]松鼠的新家 | 树上差分
- BZOJ 3631 JLOI 2014 松鼠的新家 LCA 树链剖分
- 【树链剖分】【JLOI 2014】【bzoj 3631】松鼠的新家
- bzoj 3631: [JLOI2014]松鼠的新家
- bzoj3631: [JLOI2014]松鼠的新家 (树上差分)
- BZOJ 3631 [JLOI2014]松鼠的新家
- BZOJ3631 [JLOI2014]松鼠的新家