zoukankan      html  css  js  c++  java
  • [BZOJ] 3631: [JLOI2014]松鼠的新家

    3631: [JLOI2014]松鼠的新家

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 2246  Solved: 1148
    [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

    Analysis

    树上差分的例题 qwq

    无非是树上的某一条路径点权集体+1s

    那么树上差分解决

    心情很差qwq不写教程了

    需要注意的是,题目有一个要求:每次移动的终点权值-1s

    Code

     1 #include<cstdio>
     2 #include<iostream>
     3 #define maxn 303030
     4 using namespace std;
     5 
     6 int depth[maxn],val[maxn],n,arr[maxn],fa[maxn][20];
     7 
     8 struct edge{
     9     int from,v;
    10 }e[maxn*2];
    11 int tot,first[maxn];
    12 void insert(int u,int v){
    13     tot++; e[tot].from = first[u]; e[tot].v = v;
    14     first[u] = tot;
    15 }
    16 
    17 void dfs(int now){
    18     for(int i = first[now];i;i = e[i].from){
    19         int v = e[i].v;
    20         if(v != fa[now][0]){
    21             depth[v] = depth[now]+1;
    22             fa[v][0] = now;
    23             dfs(v);
    24         }
    25     }
    26 }
    27 
    28 void dfs2(int now){
    29     for(int i = first[now];i;i = e[i].from){
    30         int v = e[i].v;
    31         if(v != fa[now][0]){
    32             dfs2(v);
    33             val[now] += val[v];
    34         }
    35     }
    36 }
    37 
    38 void Init(){
    39     for(int i = 1;i <= 18;i++)
    40     for(int j = 1;j <= n;j++)
    41         fa[j][i] = fa[fa[j][i-1]][i-1];
    42 }
    43 
    44 int LCA(int u,int v){
    45     if(depth[u] < depth[v]) swap(u,v);
    46     for(int i = 18;i > -1;i--)
    47         if(depth[fa[u][i]] >= depth[v])
    48             u = fa[u][i];
    49     if(u == v) return u;
    50     for(int i = 18;i > -1;i--)
    51         if(fa[u][i] != fa[v][i])
    52             u = fa[u][i],v = fa[v][i];
    53     return fa[u][0];
    54 }
    55 
    56 int main(){
    57     scanf("%d",&n);
    58     
    59     for(int i = 1;i <= n;i++)
    60         scanf("%d",&arr[i]);
    61     for(int i = 1;i < n;i++){
    62         int x,y; scanf("%d%d",&x,&y);
    63         insert(x,y); insert(y,x);
    64     }depth[1] = 1; dfs(1);
    65     Init();
    66     
    67     for(int i = 1;i < n;i++){
    68         int anc = LCA(arr[i],arr[i+1]);
    69         if(anc == arr[i]){
    70             val[fa[anc][0]]--,val[arr[i+1]]++;
    71         }else if(anc == arr[i+1]){
    72             val[fa[anc][0]]--,val[arr[i]]++;
    73         }else{
    74             val[fa[anc][0]]--,val[anc]--;
    75             val[arr[i]]++,val[arr[i+1]]++;
    76         }val[fa[arr[i+1]][0]]++,val[arr[i+1]]--;
    77 //        for(int i = 0;i <= n;i++) printf("%d ",val[i]);cout << endl;
    78     }dfs2(1);
    79     
    80     for(int i = 1;i <= n;i++) printf("%d
    ",val[i]);
    81     
    82     return 0;
    83 }
    心情很差
  • 相关阅读:
    Failed to read auto-increment value from storage engine错误的处理方法
    今天测试了一下 sqlalchemy 性能
    PIL The _imaging C module is not installed
    Windows下C语言调用dll动态链接库
    Linux下动态库和静态库的生成和使用
    安卓中WebKit的使用
    php使用curl扩展发送get和post请求示例
    注意笔记
    Linux下Apache2.2和PHP5的安装配置
    PHP文件上传学习
  • 原文地址:https://www.cnblogs.com/Chorolop/p/7632825.html
Copyright © 2011-2022 走看看