题目大意:
  有一棵n个点的树,每个点上有一个摄像头会在第w[i]秒拍照。
  有m个人再树上跑,第i个人沿着s[i]到t[i]的路径跑,每秒钟跑一条边。
  跑到t[i]的下一秒,人就会消失。
  问每个摄像头会拍下几个人。

思路:
  首先很显然是要求LCA的。
  求完LCA怎么办?
  我们可以用树上差分的方法分别维护向上、向下的链。
  每一条路径,我们可以在s,t,lca,par[lca]上分别打标记。
  s +dep[s]
  t +dep[t]-len
  lca -dep[s]
  par[lca] +len-dep[t]
  其中有一些是向上走的链、有一些是向下走的链,因此我们还需要将它们区分开来。
  一个点x满足条件当且仅当x在s到lca的路上且dep[x]-dep[s]=w[x],
  或者x在lca到t的路上且dep[lca]-dep[s]+deo[lca]-dep[x]=w[x]。
  最后从根节点DFS统计一下,访问到x结点就把对应的标记加进去,ans[x]=统计完子树后的答案-统计之前的答案。
  另外注意dep[t]-len可能会是负的,因此我们可以将它们整体往右移一些位置。

 #include<cstdio>
#include<cctype>
#include<vector>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return x;
}
const int N=,logN=;
std::vector<int> e[N];
inline void add_edge(const int &u,const int &v) {
e[u].push_back(v);
e[v].push_back(u);
}
int w[N],dep[N],anc[N][logN];
inline int log2(const float &x) {
return ((unsigned&)x>>&)-;
}
void dfs(const int &x,const int &par) {
dep[x]=dep[par]+;
anc[x][]=par;
for(register int i=;i<=log2(dep[x]);i++) {
anc[x][i]=anc[anc[x][i-]][i-];
}
for(register unsigned i=;i<e[x].size();i++) {
const int &y=e[x][i];
if(y==par) continue;
dfs(y,x);
}
}
inline int lca(int x,int y) {
if(dep[x]<dep[y]) std::swap(x,y);
for(register int i=log2(dep[x]-dep[y]);i>=;i--) {
if(dep[anc[x][i]]>=dep[y]) {
x=anc[x][i];
}
}
if(x==y) return x;
for(register int i=log2(dep[x]);i>=;i--) {
if(anc[x][i]!=anc[y][i]) {
x=anc[x][i];
y=anc[y][i];
}
}
return anc[x][];
}
struct Tag {
bool type;
int val,sgn;
};
std::vector<Tag> tag[N];
int ans[N];
int cnt1[N<<],cnt2[N<<];
void stat(const int &x) {
const int tmp=cnt1[dep[x]+w[x]]+cnt2[dep[x]-w[x]+(N<<)];
for(register unsigned i=;i<tag[x].size();i++) {
const Tag &t=tag[x][i];
(t.type?cnt1:cnt2)[t.val]+=t.sgn;
}
for(unsigned i=;i<e[x].size();i++) {
const int &y=e[x][i];
if(y==anc[x][]) continue;
stat(y);
}
ans[x]=cnt1[dep[x]+w[x]]+cnt2[dep[x]-w[x]+(N<<)]-tmp;
}
int main() {
const int n=getint(),m=getint();
for(register int i=;i<n;i++) {
add_edge(getint(),getint());
}
for(register int i=;i<=n;i++) {
w[i]=getint();
}
dfs(,);
for(register int i=;i<m;i++) {
const int s=getint(),t=getint(),p=lca(s,t),len=dep[s]+dep[t]-(dep[p]<<);
tag[s].push_back((Tag){,dep[s],});
tag[t].push_back((Tag){,dep[t]-len+(N<<),});
tag[p].push_back((Tag){,dep[s],-});
tag[anc[p][]].push_back((Tag){,dep[t]-len+(N<<),-});
}
stat();
for(register int i=;i<n;i++) {
printf("%d ",ans[i]);
}
printf("%d",ans[n]);
return ;
}

[NOIp2016提高组]天天爱跑步的更多相关文章

  1. P1600 [NOIP2016 提高组] 天天爱跑步 (树上差分)

    对于一条路径,s-t,位于该路径上的观察员能观察到运动员当且仅当以下两种情况成立:(d[ ]表示节点深度) 1.观察员x在s-lca(s,t)上时,满足d[s]=d[x]+w[x]就能观察到,所以我们 ...

  2. NOIP2016提高组解题报告

    NOIP2016提高组解题报告 更正:NOIP day1 T2天天爱跑步 解题思路见代码. NOIP2016代码整合

  3. 【题解】NOIP2016提高组 复赛

    [题解]NOIP2016提高组 复赛 传送门: 玩具谜题 \(\text{[P1563]}\) 天天爱跑步 \(\text{[P1600]}\) 换教室 \(\text{[P1850]}\) 组合数问 ...

  4. 【题解】NOIP2016 提高组 简要题解

    [题解]NOIP2016 提高组 简要题解 玩具迷题(送分) 用异或实现 //@winlere #include<iostream> #include<cstdio> #inc ...

  5. [NOIP2016 DAY1 T2]天天爱跑步-[差分+线段树合并][解题报告]

    [NOIP2016 DAY1 T2]天天爱跑步 题面: B[NOIP2016 DAY1]天天爱跑步 时间限制 : - MS 空间限制 : 565536 KB 评测说明 : 2s Description ...

  6. BZOJ4719[NOIP2016提高组Day1T2] 天天爱跑步

    #261. [NOIP2016]天天爱跑步 描述 提交 自定义测试 小C同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是一个养成类游戏,需要玩家 ...

  7. 【NOIP2016提高组复赛day2】天天爱跑步

    题目 小 C 同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏. <天天爱跑步>是一个养成类游戏,需要玩家每天按时上线,完成打卡任务. 这个游戏的地图可以看作一棵 ...

  8. Luogu P1600[NOIP2016]day1 T2天天爱跑步

    号称是noip2016最恶心的题 基本上用了一天来搞明白+给sy讲明白(可能还没讲明白 具体思路是真的不想写了(快吐了 如果要看,参见洛谷P1600 天天爱跑步--题解 虽然这样不好但我真的不想写了 ...

  9. [日记&做题记录]-Noip2016提高组复赛 倒数十天

    写这篇博客的时候有点激动 为了让自己不颓 还是写写日记 存存模板 Nov.8 2016 今天早上买了两个蛋挞 吃了一个 然后就做数论(前天晚上还是想放弃数论 但是昨天被数论虐了 woc noip模拟赛 ...

随机推荐

  1. 一个python拖库字段的小脚本

    import requests import re all_column = dict() all_db = "db_zf,dg_activity,dg_activity_log,dg_ad ...

  2. vue-混入mixin

    混入 基础 混入 (mixins) 是一种分发 Vue 组件中可复用功能的非常灵活的方式.混入对象可以包含任意组件选项.当组件使用混入对象时,所有混入对象的选项将被混入该组件本身的选项. 例子: // ...

  3. DTW 算法(转)

    DTW为(Dynamic Time Warping,动态时间归准)的简称.应用很广,主要是在模板匹配中,比如说用在孤立词语音识别,计算机视觉中的行为识别,信息检索等中.可能大家学过这些类似的课程都看到 ...

  4. 64_c1

    CBFlib-0.9.5.15-3.fc26.i686.rpm 05-Feb-2017 21:55 427710 CBFlib-0.9.5.15-3.fc26.x86_64.rpm 05-Feb-20 ...

  5. [ Python ] 基本数据类型及属性(上篇)

    1. 基本数据类型 (1) 数字 - int        (2) 字符串 - str        (3) 布尔值 - bool 2. int 类型中重要的方法 (1) int      将字符串转 ...

  6. vue的data用到this问题

    问题:在vue中用vue-awesome-swiper,在data中初始化,用到swiper一个方法onTap,然后再调vue的一个函数,用到this,可是... data() { return { ...

  7. 关于自适应屏幕,设置子元素浮动,父div不能包裹子div,子元素中内容溢出的问题。

    设置HTML适应不同分辨率的屏幕. 需求结构如下: HTML结构代码如下(只是其中一条): <body> <div class="content">< ...

  8. 高性能网络服务器--I/O复用 select poll epoll_wait之间的区别

    一.select select采用的是集合的方式,最多只能访问1024个套接字.可读,可写,异常,三种访问,并且采用的是轮训的方式进行每次访问都需要从内核向用户空间拷贝 二.poll poll采用的是 ...

  9. 【hdoj_2079】选课时间(母函数)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=2079 此题采用母函数的知识求解,套用母函数模板即可: http://blog.csdn.net/ten_s ...

  10. Prometheus exporter的Node exporter是可以独立安装,用来测试的

    现在慢慢在把prometheus operator的一些概念组织完整. https://github.com/coreos/prometheus-operator/tree/master/contri ...