zoukankan      html  css  js  c++  java
  • [NOIP2016]天天爱跑步

    NOIP2016D1T2......

    我连D1T2都需要看题解才能做了......

    AFO......

    题目传送门

    解析:

    考虑有一个玩家,其起点为$u$,终点为$v$。

    则其路径可以分成两部分,一部分为$u->lca(u,v)$,另一部分为$lca(u,v)->v$

    对于前半部分,可以对点x(x在从下至上的路径上)产生贡献当且仅当$dis(u,x)=w_x$

    由于边权均为1,因此它可以化简为$dep_u-dep_x=w_x$,然后移项得$dep_u=dep_x+w_x$

    对于后半部分,当且仅当$dis(u,v)-dis(x,v)=w_x$时,可以产生贡献,化简得

    $dep_u-2*dep_lca(u,v)=w_x-dep_x$.

    因此可以使用树上差分维护一些桶,然后取每个点被贡献的总数,对恰好在LCA的点要-1(会被计算两次)

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<vector>
     5 #define N 600005
     6 using namespace std;
     7 int read()
     8 {
     9     int x=0,f=1;char ch=getchar();
    10     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    11     while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    12     return x*f;
    13 }
    14 struct tag{int v,siz;};
    15 int n,m,w[N],s[N],t[N],LCA[N],fa[N][21],T1[N+N],T2[N+N],father[N],dep[N],cnt[N];
    16 vector<int>G[N];
    17 vector<tag>tag1[N],tag2[N];
    18 void dfs1(int x)
    19 {
    20     dep[x]=dep[father[x]]+1;
    21     for(int i=0;i<=19;i++)fa[x][i+1]=fa[fa[x][i]][i];
    22     int sz=G[x].size(); 
    23     for(int i=0;i<sz;i++)
    24     {
    25         if(G[x][i]==father[x])continue;
    26         father[G[x][i]]=fa[G[x][i]][0]=x;
    27         dfs1(G[x][i]);
    28     }
    29 }
    30 int lca(int x,int y)
    31 {
    32     if(dep[x]<dep[y])swap(x,y);
    33     for(int i=20;i>=0;i--)
    34     {
    35         if(dep[fa[x][i]]>=dep[y])x=fa[x][i];
    36         if(x==y)return x;
    37     }
    38     for(int i=20;i>=0;i--)
    39     {
    40         if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];
    41     }
    42     return fa[x][0]; 
    43 }
    44 void dfs(int x,int a,int b)
    45 {
    46     int sz=tag1[x].size();
    47     for(int i=0;i<sz;i++)T1[tag1[x][i].v+N]+=tag1[x][i].siz;
    48     sz=tag2[x].size();
    49     for(int i=0;i<sz;i++)T2[tag2[x][i].v+N]+=tag2[x][i].siz;
    50     sz=G[x].size();
    51     for(int i=0;i<sz;i++)
    52     {
    53         if(G[x][i]==father[x])continue;
    54         dfs(G[x][i],T1[w[G[x][i]]+dep[G[x][i]]+N],T2[w[G[x][i]]-dep[G[x][i]]+N]);
    55     }
    56     cnt[x]+=T1[w[x]+dep[x]+N]+T2[w[x]-dep[x]+N]-a-b;
    57 }
    58 int main()
    59 {
    60     n=read();m=read();
    61     for(int x,y,i=1;i<n;i++)
    62     {
    63         x=read();y=read();
    64         G[x].push_back(y);
    65         G[y].push_back(x);
    66     }
    67     for(int i=1;i<=n;i++)w[i]=read();
    68     dfs1(1);
    69     for(int i=1;i<=m;i++)s[i]=read(),t[i]=read(),LCA[i]=lca(s[i],t[i]);
    70     for(int i=1;i<=m;i++)
    71     {
    72         if(w[LCA[i]]+dep[LCA[i]]==dep[s[i]])--cnt[LCA[i]];
    73         tag1[s[i]].push_back((tag){dep[s[i]],1});
    74         tag1[father[LCA[i]]].push_back((tag){dep[s[i]],-1});
    75         tag2[t[i]].push_back((tag){dep[s[i]]-2*dep[LCA[i]],1});
    76         tag2[father[LCA[i]]].push_back((tag){dep[s[i]]-2*dep[LCA[i]],-1});
    77     }
    78     dfs(1,0,0);
    79     for(int i=1;i<=n;i++)printf("%d ",cnt[i]);
    80     return 0;
    81 }
    82 //up:dep[s]=w[i]+dep[i];
    83 //down:dis(s,t)-(dep[t]-dep[i])=w[i];
    84 //=>dep[s]+dep[t]-2*dep[lca(s,t)]-dep[t]+dep[i]=w[i];
    85 //=>dep[s]-2*dep[lca(s,t)]=w[i]-dep[i]
    View Code
  • 相关阅读:
    mysql乐观锁总结和实践
    linux使用文本编辑器vi常用命令
    python高级特性-sorted()
    python高级特性-filter
    Python函数式编程-map/reduce
    centos 7.3 快速安装ceph
    python高级特性-迭代器
    python高级特性-生成器
    python高级特性-列表生成
    python高级特性-迭代
  • 原文地址:https://www.cnblogs.com/szmssf/p/11588019.html
Copyright © 2011-2022 走看看