zoukankan      html  css  js  c++  java
  • 洛谷 3285 [JLOI2014]松鼠的新家

    【题解】

      给出一条路径,问树上的点被经过了几次。

      显然树剖之后树上差分就好了。

      

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define N 300010
     4 #define rg register
     5 using namespace std;
     6 int n,tot,last[N],dep[N],fa[N],size[N],son[N],val[N],top[N],a[N];
     7 struct edge{
     8     int to,pre;
     9 }e[N<<1];
    10 inline int read(){
    11     int k=0,f=1; char c=getchar();
    12     while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
    13     while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
    14     return k*f;
    15 }
    16 void dfs1(int x){
    17     size[x]=1; dep[x]=dep[fa[x]]+1;
    18     for(rg int i=last[x],to;i;i=e[i].pre) if((to=e[i].to)!=fa[x]){
    19         fa[to]=x; dfs1(to);
    20         size[x]+=size[to];
    21         if(size[to]>size[son[x]]) son[x]=to;
    22     }
    23 }
    24 void dfs2(int x,int tp){
    25     top[x]=tp;
    26     if(son[x]) dfs2(son[x],tp);
    27     for(rg int i=last[x],to;i;i=e[i].pre) 
    28         if((to=e[i].to)!=son[x]&&to!=fa[x]) dfs2(to,to);
    29 }
    30 inline int lca(int x,int y){
    31     int f1=top[x],f2=top[y];
    32     while(f1!=f2){
    33         if(dep[f1]<dep[f2]) swap(x,y),swap(f1,f2);
    34         x=fa[f1]; f1=top[x];
    35     }
    36     return dep[x]<dep[y]?x:y;
    37 }
    38 void dfs(int x){
    39     for(rg int i=last[x],to;i;i=e[i].pre) if((to=e[i].to)!=fa[x]){
    40         dfs(to);
    41         val[x]+=val[to];
    42     }
    43 }
    44 int main(){
    45     n=read();
    46     for(rg int i=1;i<=n;i++) a[i]=read();
    47     for(rg int i=1;i<n;i++){
    48         int u=read(),v=read();
    49         e[++tot]=(edge){v,last[u]}; last[u]=tot;
    50         e[++tot]=(edge){u,last[v]}; last[v]=tot;
    51     }
    52     dfs1(1);
    53     dfs2(1,1);
    54     for(rg int i=2;i<=n;i++){
    55         int L=lca(a[i],a[i-1]);
    56         val[a[i]]++; val[a[i-1]]++; val[L]--; val[fa[L]]--;
    57         //printf("lca=%d
    ",L);
    58     }
    59     dfs(1);
    60     for(rg int i=2;i<=n;i++) val[a[i]]--;
    61     for(rg int i=1;i<=n;i++) printf("%d
    ",val[i]);
    62     return 0;
    63 }
    View Code
  • 相关阅读:
    CUDA和cudnn的环境变量设置问题
    zsh-Ubuntu更实用终端
    应用安全
    应用安全
    应用安全
    操作系统
    应用安全
    应用安全
    操作系统
    密码学
  • 原文地址:https://www.cnblogs.com/DriverLao/p/8707326.html
Copyright © 2011-2022 走看看