zoukankan      html  css  js  c++  java
  • NOIP2016 天天爱跑步(树上差分)

    题意

    给定一棵树,从时刻 0 开始,有若干人从 S[i] 出发向 T[i] 移动,每单位时刻移动一条边

    对于树上每个点 x,求 w[x]  时刻有多少人恰好路过 x

    N,M≤300000

    题解

    从上午11点做到下午3点45终于做出来了。

    一开始坚持自己的想法,发现错了之后不知道怎么改,无奈看了题解。

    列出恰好路过的条件并化简
    在 Si 到 lca(Si,Ti ) 阶段,应满足 d[Si ]=w[x]+d[x]
    在 lca(Si,Ti ) 到 Ti阶段,应满足 d[Si]-2∗d[lca(Si,Ti )]=w[x]-d[x]
    相当于在 Si 位置出现一个 A 类数 d[Si ],在 lca(Si,Ti ) 的父节点消失
    在 Ti 位置出现一个 B 类数 d[Si ]-2∗d[lca(Si,Ti )],在 lca(Si,Ti ) 消失
    求子树 x 中,等于 w[x]+d[x] 的 A 类数个数 + 等于 w[x]-d[x] 的 B 类数个数
    全局数组计数,统计遍历子树 x 前后相应位置上的差我一开始就是没注意这死活调不出来
      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdio>
      4 #include<cmath>
      5 #include<algorithm>
      6 #include<vector>
      7 using namespace std;
      8 const int N=300010;
      9 vector<int> v1[N],v2[N],v3[N],v4[N];
     10 int cnt,head[N];
     11 int fa[N][32],dep[N];
     12 int book1[N],book2[N*2];
     13 int n,m,w[N],ans[N];
     14 struct edge{
     15     int to,nxt;
     16 }e[N*2];
     17 void add(int u,int v){
     18     cnt++;
     19     e[cnt].nxt=head[u];
     20     e[cnt].to=v;
     21     head[u]=cnt;
     22 }
     23 void dfs1(int u,int f,int deep){
     24     fa[u][0]=f;
     25     dep[u]=deep;
     26     for(int i=head[u];i;i=e[i].nxt){
     27         int v=e[i].to;
     28         if(v==f)continue;
     29         dfs1(v,u,deep+1);
     30     }
     31 }
     32 int lca(int u,int v){
     33     if(dep[u]<dep[v])swap(u,v);
     34     for(int i=30;i>=0;i--){
     35         if(dep[fa[u][i]]>=dep[v])u=fa[u][i];
     36     }
     37     if(u==v)return u;
     38     for(int i=30;i>=0;i--){
     39         if(fa[u][i]!=fa[v][i]){
     40             u=fa[u][i];v=fa[v][i];
     41         }
     42     }
     43     return fa[u][0];
     44 }
     45 void dfs2(int u){
     46     ans[u]=book1[w[u]+dep[u]]+book2[w[u]-dep[u]+N];
     47     for(int i=0;i<v1[u].size();i++){
     48         book1[v1[u][i]]++;
     49     }
     50     for(int i=0;i<v2[u].size();i++){
     51         book1[v2[u][i]]--;
     52     }
     53     for(int i=0;i<v3[u].size();i++){
     54         book2[v3[u][i]]++;
     55     }
     56     for(int i=0;i<v4[u].size();i++){
     57         book2[v4[u][i]]--;
     58     }
     59     for(int i=head[u];i;i=e[i].nxt){
     60         int v=e[i].to;
     61         if(v==fa[u][0])continue;
     62         dfs2(v);
     63     }
     64     ans[u]=book1[w[u]+dep[u]]+book2[w[u]-dep[u]+N]-ans[u];
     65 }
     66 int main(){
     67     scanf("%d%d",&n,&m);
     68     for(int i=1;i<=n-1;i++){
     69         int u,v;
     70         scanf("%d%d",&u,&v);
     71         add(u,v);
     72         add(v,u);
     73     }
     74     dfs1(1,0,1);
     75     for(int i=1;i<=30;i++)
     76         for(int j=1;j<=n;j++)
     77             fa[j][i]=fa[fa[j][i-1]][i-1];
     78     for(int i=1;i<=n;i++){
     79         scanf("%d",&w[i]);
     80     }
     81     for(int i=1;i<=m;i++){
     82         int u,v;
     83         scanf("%d%d",&u,&v);
     84         int c=lca(u,v);
     85         v1[u].push_back(dep[u]);
     86         v2[fa[c][0]].push_back(dep[u]);
     87         v3[v].push_back(dep[u]-2*dep[c]+N);
     88         v4[c].push_back(dep[u]-2*dep[c]+N);
     89     }
     90     for(int i=0;i<v1[0].size();i++){
     91         book1[v1[0][i]]++;
     92     }
     93     for(int i=0;i<v2[0].size();i++){
     94         book1[v2[0][i]]--;
     95     }
     96     for(int i=0;i<v3[0].size();i++){
     97         book2[v3[0][i]]++;
     98     }
     99     for(int i=0;i<v4[0].size();i++){
    100         book2[v4[0][i]]--;
    101     }
    102     dfs2(1);
    103     for(int i=1;i<=n;i++){
    104         printf("%d ",ans[i]);
    105     }
    106     return 0;
    107 }
    View Code
  • 相关阅读:
    Springboot集成Junit
    springboot集成mybatis
    使用Spring Initializr快速创建Springboot工程
    Tungsten Replicator学习总结
    Java代理模式汇总
    Java定时任务的常用实现
    Java对象序列化剖析
    最适合作为Java基础面试题之Singleton模式
    MyCat源码分析系列之——结果合并
    MyCat源码分析系列之——SQL下发
  • 原文地址:https://www.cnblogs.com/Xu-daxia/p/9385568.html
Copyright © 2011-2022 走看看