zoukankan      html  css  js  c++  java
  • 【JLOI2014】松鼠的新家

    题面

    松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的。天哪,他居然真的住在”树“上。

    松鼠想邀请小熊维尼前来参观,并且还指定一份参观指南,他希望维尼能够按照他的指南顺序,先去a1,再去a2,......,最后到an,去参观新家。可是这样会导致维尼重复走很多房间,懒惰的维尼不停地推辞。可是松鼠告诉他,每走到一个房间,他就可以从房间拿一块糖果吃。

    维尼是个馋家伙,立马就答应了。现在松鼠希望知道为了保证维尼有糖果吃,他需要在每一个房间各放至少多少个糖果。

    因为松鼠参观指南上的最后一个房间an是餐厅,餐厅里他准备了丰盛的大餐,所以当维尼在参观的最后到达餐厅时就不需要再拿糖果吃了。

    2<= n <=300000

    分析

    很明显的树上点差分,但是直接标记不太对,因为会有既是起点又是终点的点被标记两次。

    我们只需要将差分的子树和求出来后在ans里对2~n-1个点每个点减一,由于最后一个点是餐厅,所以也也减一。

    代码

    1. #include<bits/stdc++.h>  
    2. using namespace std;  
    3. #define N 300030  
    4. int n,cnt;  
    5. int a[N],c[N],ans[N],dep[N],first[N],fa[N][20];  
    6. struct email  
    7. {  
    8.     int u,v;  
    9.     int nxt;  
    10. }e[N*4];  
    11. inline void add(int u,int v)  
    12. {  
    13.     e[++cnt].nxt=first[u];first[u]=cnt;  
    14.     e[cnt].u=u;e[cnt].v=v;  
    15. }  
    16. template<class T>  
    17. inline void read(T &x)  
    18. {  
    19.     x=0;int f=1;static char c=getchar();   
    20.     while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}  
    21.     while(c>='0'&&c<='9'){x=x*10+c-'0',c=getchar();}  
    22.     x*=f;  
    23. }  
    24. inline void pre(int u,int f)  
    25. {  
    26.     for(int i=1;(1<<i)<=dep[u];i++)  
    27.         fa[u][i]=fa[fa[u][i-1]][i-1];  
    28.     for(int i=first[u];i;i=e[i].nxt)  
    29.     {  
    30.         int v=e[i].v;  
    31.         if(v==f)continue;  
    32.         dep[v]=dep[u]+1;  
    33.         fa[v][0]=u;  
    34.         pre(v,u);  
    35.     }  
    36. }  
    37.   
    38. inline int lca(int x,int y)  
    39. {  
    40.     if(dep[x]<dep[y])swap(x,y);  
    41.     int t=dep[x]-dep[y];  
    42.     for(int i=0;(1<<i)<=t;i++)  
    43.         if((1<<i)&t)  
    44.             x=fa[x][i];  
    45.     if(x==y)return x;  
    46.     for(int i=19;i>=0;i--)  
    47.         if(fa[x][i]!=fa[y][i])  
    48.             x=fa[x][i],y=fa[y][i];  
    49.     return fa[x][0];  
    50. }   
    51.   
    52. inline void dfs(int u,int f)  
    53. {  
    54.     for(int i=first[u];i;i=e[i].nxt)  
    55.     {  
    56.         int v=e[i].v;  
    57.         if(v==f)continue;  
    58.         dfs(v,u);  
    59.         c[u]+=c[v];   
    60.     }  
    61.     ans[u]=c[u];  
    62. }  
    63.   
    64. int main()  
    65. {  
    66.     read(n);  
    67.     for(int i=1;i<=n;i++)read(a[i]);  
    68.     for(int i=1;i<n;i++)  
    69.     {  
    70.         int u,v;  
    71.         read(u),read(v);  
    72.         add(u,v);add(v,u);  
    73.     }   
    74.     pre(1,0);  
    75.     for(int i=1;i<n;i++)  
    76.     {  
    77.         int u=a[i],v=a[i+1],LCA=lca(u,v);  
    78.         c[u]++,c[v]++,c[LCA]--,c[fa[LCA][0]]--;  
    79.     }  
    80.     dfs(1,0);  
    81.     for(int i=2;i<=n;i++)ans[a[i]]--;  
    82.     for(int i=1;i<=n;i++)printf("%d ",ans[i]);;  
    83.     return 0;  
    84. }  
  • 相关阅读:
    Laravel-RestfulAPI 资源控制器(全面详解)
    Laravel 支付宝SDK在Laravel5的封装
    Laravel 集成 阿里大于 短信接口
    Laravel --进阶篇 (单用户登录)
    Laravel LTS 分割 路由文件的最佳方式
    Laravel -- 实战篇 自制二维码 Simple QrCode
    Laravel 使用 Aliyun OSS 云存储
    Laravel 富文本插件-Ueditor
    Laravel 实战篇
    Laravel 微信开发组件-WeChat 微信支付
  • 原文地址:https://www.cnblogs.com/NSD-email0820/p/9854267.html
Copyright © 2011-2022 走看看