题目大意:
  有一棵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. mysql in/no in/like

    % 任意字符 _ 任意一个字符 in (value,......) 在这里 not in (value,......) 不在这里 mysql> select 'a' not in (1,2,3, ...

  2. 通过编译函数库来学习GCC【转】

    转自:http://blog.csdn.net/u012365926/article/details/51446295 基本概念 什么是库 在windows平台和linux平台下都大量存在着库. 本质 ...

  3. fbx sdk

    autodesk fbx review autodesk fbx review http://www.greenxf.com/soft/169025.html autodesk fbx review( ...

  4. python并发模块之concurrent.futures(一)

    Python3.2开始,标准库为我们提供了concurrent.futures模块,它提供了ThreadPoolExecutor和ProcessPoolExecutor两个类,实现了对threadin ...

  5. MVC使用Newtonsoft无需实体类,实现JSON数据返回给前端页面使用

    //引用using Newtonsoft.Json; using Newtonsoft.Json.Linq; public ActionResult JsonSample() { ResponseRe ...

  6. HTML+CSS+JS(+Vue)写一个通讯录组件

    求各位大大的Star(*/ω\*). 没有录屏,所以上传的是图片.后面已补充录屏效果. 效果:(主要是参考小米Note3的通讯录的效果做的) 主要功能: 1. 滚动后,通讯录的模块标题会固定在顶部(图 ...

  7. [总结]可重用cell的定义方式

    1.简介 为了提高tableview中cell的加载速度通常可以使用cell重用的方式来实现,即我们向上拖动cell的时候,上部份消失的cell可以重复的被下部分出现的cell重用. 2.说明 一般c ...

  8. 看懂sh脚本

    1 开头 程序必须以下面的行开始(必须方在文件的第一行): #!/bin/sh 符号#!用来告诉系统它后面的参数是用来执行该文件的程序.在这个例子中我们使用/bin/sh来执行程序. 当编写脚本完成时 ...

  9. django “如何”系列3:如何编写模型域(model filed)

    django自带很多的域类--CharField,DateField等等--,如果django的这些域都不能满足你精确的要求,那么你可以编写自己的模型域. django自带的域没有和数据库列类型一一对 ...

  10. addeventlistener监听scroll跟touch

    这三个事件只在手机上生效 touchstart,手指开始触屏 touchmove,手指移动 touchend,手指触屏结束   这个事件在手机上跟在pc端都生效 scroll事件     addeve ...