题意

给定一棵树,从时刻 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 前后相应位置上的差我一开始就是没注意这死活调不出来
 #include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
const int N=;
vector<int> v1[N],v2[N],v3[N],v4[N];
int cnt,head[N];
int fa[N][],dep[N];
int book1[N],book2[N*];
int n,m,w[N],ans[N];
struct edge{
int to,nxt;
}e[N*];
void add(int u,int v){
cnt++;
e[cnt].nxt=head[u];
e[cnt].to=v;
head[u]=cnt;
}
void dfs1(int u,int f,int deep){
fa[u][]=f;
dep[u]=deep;
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(v==f)continue;
dfs1(v,u,deep+);
}
}
int lca(int u,int v){
if(dep[u]<dep[v])swap(u,v);
for(int i=;i>=;i--){
if(dep[fa[u][i]]>=dep[v])u=fa[u][i];
}
if(u==v)return u;
for(int i=;i>=;i--){
if(fa[u][i]!=fa[v][i]){
u=fa[u][i];v=fa[v][i];
}
}
return fa[u][];
}
void dfs2(int u){
ans[u]=book1[w[u]+dep[u]]+book2[w[u]-dep[u]+N];
for(int i=;i<v1[u].size();i++){
book1[v1[u][i]]++;
}
for(int i=;i<v2[u].size();i++){
book1[v2[u][i]]--;
}
for(int i=;i<v3[u].size();i++){
book2[v3[u][i]]++;
}
for(int i=;i<v4[u].size();i++){
book2[v4[u][i]]--;
}
for(int i=head[u];i;i=e[i].nxt){
int v=e[i].to;
if(v==fa[u][])continue;
dfs2(v);
}
ans[u]=book1[w[u]+dep[u]]+book2[w[u]-dep[u]+N]-ans[u];
}
int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=n-;i++){
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
dfs1(,,);
for(int i=;i<=;i++)
for(int j=;j<=n;j++)
fa[j][i]=fa[fa[j][i-]][i-];
for(int i=;i<=n;i++){
scanf("%d",&w[i]);
}
for(int i=;i<=m;i++){
int u,v;
scanf("%d%d",&u,&v);
int c=lca(u,v);
v1[u].push_back(dep[u]);
v2[fa[c][]].push_back(dep[u]);
v3[v].push_back(dep[u]-*dep[c]+N);
v4[c].push_back(dep[u]-*dep[c]+N);
}
for(int i=;i<v1[].size();i++){
book1[v1[][i]]++;
}
for(int i=;i<v2[].size();i++){
book1[v2[][i]]--;
}
for(int i=;i<v3[].size();i++){
book2[v3[][i]]++;
}
for(int i=;i<v4[].size();i++){
book2[v4[][i]]--;
}
dfs2();
for(int i=;i<=n;i++){
printf("%d ",ans[i]);
}
return ;
}

NOIP2016 天天爱跑步(树上差分)的更多相关文章

  1. 洛谷 1600 (NOIp2016) 天天爱跑步——树上差分

    题目:https://www.luogu.org/problemnew/show/P1600 看TJ:https://blog.csdn.net/clove_unique/article/detail ...

  2. NOIP2016 天天爱跑步 (树上差分+dfs)

    题目大意:给你一颗树,树上每个点都有一个观察员,他们仅会在 w[i] 时刻出现,观察正在跑步的玩家 一共有m个玩家,他们分别从节点 s[i] 同时出发,以每秒跑一条边的速度,沿着到 t[i] 的唯一路 ...

  3. [NOIP2016]天天爱跑步(树上差分+线段树合并)

    将每个人跑步的路径拆分成x->lca,lca->y两条路径分别考虑: 对于在点i的观察点,这个人(s->t)能被观察到的充要条件为: 1.直向上的路径:w[i]=dep[s]-dep ...

  4. NOIP2016 天天爱跑步 - 树上差分

    传送门 题目分析: 一年前还是个傻子的时候居然直接放弃了这题. 首先列出两个方程:如果i节点的观察员能够观察到由s->t的那个人,那么: \[dep[s] - dep[i] = w[i], de ...

  5. NOIP2016 Day1 T2 天天爱跑步(树上差分,LCA)

    原文链接 原题链接 题目描述 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是一个养成类游戏,需要玩家每天按时上线,完成打卡任务. 这个游戏 ...

  6. 洛谷P1600 天天爱跑步——树上差分

    题目:https://www.luogu.org/problemnew/show/P1600 看博客:https://blog.csdn.net/clove_unique/article/detail ...

  7. 洛谷$P1600$ 天天爱跑步 树上差分

    正解:树上差分 解题报告: 传送门$QwQ$! 这题还挺妙的,,,我想了半天才会$kk$ 首先对一条链$S-T$,考虑先将它拆成$S-LCA$和$LCA-T$,分别做.因为总体上来说差不多接下来我就只 ...

  8. BZOJ 4719--天天爱跑步(LCA&差分)

    4719: [Noip2016]天天爱跑步 Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 1464  Solved: 490[Submit][Stat ...

  9. [NOIp2016]天天爱跑步 线段树合并

    [NOIp2016]天天爱跑步 LG传送门 作为一道被毒瘤出题人们玩坏了的NOIp经典题,我们先不看毒瘤的"动态爱跑步"和"天天爱仙人掌",回归一下本来的味道. ...

  10. [Noip2016]天天爱跑步 LCA+DFS

    [Noip2016]天天爱跑步 Description 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.?天天爱跑步?是一个养成类游戏,需要玩家每天按时上线,完成打卡任 ...

随机推荐

  1. JavaScript中Array方法总览

    title: JavaScript中Array方法总览 toc: true date: 2018-10-13 12:48:14 push(x) 将x添加到数组最后,可添加多个值,返回数组长度.改变原数 ...

  2. HttpWebRequest 表单提交

    /// <summary> /// http请求 /// </summary> public static class ZkWebRequestHelp { /// <s ...

  3. POJ 3694 Network(Tarjan求割边+LCA)

    Network Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 10969   Accepted: 4096 Descript ...

  4. http状态码304

    服务器对客户端返回HTTP/1.1 304  意思是服务端告诉客户端 我的的缓存没有改变你不需要来取了,就用你自己本地的吧! 浏览器的三种缓存协商机制: if-modified-since (基于最后 ...

  5. redis中的事务、lua脚本和管道的使用场景

    参考文章 : https://blog.csdn.net/fangjian1204/article/details/50585080

  6. c traps and pitfalls reading note(1)

    1. 一直知道char *p = 'a';这样写是错误的,但是为什么是错的,没想过,今天看书解惑. p指向一个字符,但是在c中,''引起来的一个字符代表一个整数,这样指针能不报错.o(^▽^)o 2. ...

  7. Swagger 生成 PHP API 接口文档

    Swagger 生成 PHP API 接口文档 Lumen微服务生成Swagger文档 1.概况 有同学反馈写几十个接口文档需要两天的工作量, 随着多部门之间的协作越来越频繁, 维护成本越来越高, 文 ...

  8. 51nod 1079 中国剩余定理模板

    中国剩余定理就是同余方程组除数为质数的特殊情况 我直接用同余方程组解了. 记得exgcd后x要更新 还有先更新b1再更新m1,顺序不能错!!(不然会影响到b1的更新) #include<cstd ...

  9. Eclipse配置class文件输出目录

    1, Eclipse选中项目名称,邮件选中“Build Path”,然后选择“Configure Build Path”--->选择“Source” Tab---->修改"Def ...

  10. Eclipse WEB项目更改项目名

    可能很多人都碰到过 WEB 项目需要改名字的事情,不过不是每个人都能很顺畅地完成这个事情.这里简单给大家介绍两种改项目名的方法 1. 在Eclipse 中修改项目名 没错这种方法跟你预料的一样简单,当 ...