3631: [JLOI2014]松鼠的新家

来源:互联网 发布:淘宝店铺托管靠谱吗 编辑:程序博客网 时间:2024/03/28 18:09

3631: [JLOI2014]松鼠的新家

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 1806  Solved: 879
[Submit][Status][Discuss]

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

Sample Output

1
2
1
2
1

HINT

2<= n <=300000

Source

[Submit][Status][Discuss]



第一眼看题:不就是树上链加么,写个树链剖分。。。

TLE飞了。。估计是所有点只存在一棵线段树上导致复杂度O(nlog^2)的缘故吧。。。

可是题目并没有要求在线询问呀。。。所以树上前缀和不就好了么。。。?

#include<iostream>#include<cstdio>#include<vector>#include<queue>using namespace std; const int maxn = 3E5 + 30;const int T = 19; int n,fa[maxn][T],L[maxn],Ans[maxn],son[maxn],A[maxn]; vector <int> v[maxn];queue <int> Q; void Dfs(int x,int from){    for (int i = 1; i < T; i++) fa[x][i] = fa[fa[x][i-1]][i-1];    for (int i = 0; i < v[x].size(); i++)    {        int to = v[x][i];        if (to == from) continue; ++son[x];        L[to] = L[x] + 1; fa[to][0] = x; Dfs(to,x);    }} int LCA(int p,int q){    if (L[p] < L[q]) swap(p,q);    for (int i = T - 1; i >= 0; i--)        if (L[p] - (1 << i) >= L[q])            p = fa[p][i];    if (p == q) return p;    for (int i = T - 1; i >= 0; i--)        if (fa[p][i] != fa[q][i])            p = fa[p][i],q = fa[q][i];    return fa[p][0];} int getint(){    char ch = getchar(); int ret = 0;    while (ch < '0' || '9' < ch) ch = getchar();    while ('0' <= ch && ch <= '9')        ret = ret * 10 + ch - '0',ch = getchar();    return ret;} int main(){    #ifdef DMC        freopen("DMC.txt","r",stdin);    #endif         n = getint();    for (int i = 1; i <= n; i++) A[i] = getint();    for (int i = 1; i < n; i++)    {        int x = getint(),y = getint();        v[x].push_back(y);        v[y].push_back(x);    }    L[1] = 1; Dfs(1,0);    for (int i = 1; i < n; i++)    {        int x = A[i],y = A[i+1],lca = LCA(x,y);        if (lca == x) ++Ans[fa[y][0]],--Ans[fa[x][0]];        else if (lca == y) ++Ans[x],--Ans[y];        else        {            ++Ans[x]; ++Ans[fa[y][0]];            --Ans[lca]; --Ans[fa[lca][0]];        }    }    for (int i = 1; i <= n; i++)        if (!son[i]) Q.push(i);    while (!Q.empty())    {        int k = Q.front(); Q.pop(); if (k == 1) break;        Ans[fa[k][0]] += Ans[k]; --son[fa[k][0]];        if (!son[fa[k][0]]) Q.push(fa[k][0]);    }    for (int i = 1; i <= n; i++) printf("%d\n",Ans[i]);    return 0;}

0 0
原创粉丝点击