长久以来的心理阴影?但是其实非常简单……

预处理出deep和每组st的lca,在这里我简单粗暴的拿树剖爆算了

然后考虑对于一组s t lca来说,被这组贡献的观察员x当且仅当:

x在s到lca的路径上,且w[x]de[s]-de[x]——>de[x]+w[x]de[s];

x在lca到t的路径上,且w[x]de[x]-de[lca]+de[s]-de[lca]——>de[x]-w[x]de[s]-2de[lca];

然后把这一段拆成四个点(树上差分),一遍dfs统计状态即可

注意,因为w==0时答案会被统计两遍,所以要除二

可是我居然因为数组大小多用了1h???我怕不是个zz

#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
const int N=600005;
int n,m,h[N],cnt,w[N],s[N],t[N],de[N],fa[N],si[N],fr[N],hs[N],lc[N],d[N],ans[N];
struct qwe
{
int ne,to;
}e[N<<1];
struct tg
{
int p,c;
tg(int P=0,int C=0)
{
p=P,c=C;
}
};
vector<tg>a[N];
int read()
{
int r=0,f=1;
char p=getchar();
while(p>'9'||p<'0')
{
if(p=='-')
f=-1;
p=getchar();
}
while(p>='0'&&p<='9')
{
r=r*10+p-48;
p=getchar();
}
return r*f;
}
void add(int u,int v)
{
cnt++;
e[cnt].ne=h[u];
e[cnt].to=v;
h[u]=cnt;
}
void dfs1(int u,int fat)
{
si[u]=1;
fa[u]=fat;
de[u]=de[fat]+1;
for(int i=h[u];i;i=e[i].ne)
if(e[i].to!=fat)
{
dfs1(e[i].to,u);
si[u]+=si[e[i].to];
if(si[e[i].to]>si[hs[u]])
hs[u]=e[i].to;
}
}
void dfs2(int u,int top)
{
fr[u]=top;
if(!hs[u])
return;
dfs2(hs[u],top);
for(int i=h[u];i;i=e[i].ne)
if(e[i].to!=fa[u]&&e[i].to!=hs[u])
dfs2(e[i].to,e[i].to);
}
int lca(int u,int v)
{
for(;fr[u]!=fr[v];de[fr[u]]>de[fr[v]]?u=fa[fr[u]]:v=fa[fr[v]]);
return de[u]<de[v]?u:v;
}
void dfs(int u)
{
int x=d[de[u]+w[u]],y=d[de[u]-w[u]];
for(int i=h[u];i;i=e[i].ne)
if(e[i].to!=fa[u])
dfs(e[i].to);
for(int i=0;i<a[u].size();i++)
d[a[u][i].p]+=a[u][i].c;
ans[u]+=d[de[u]+w[u]]-x+d[de[u]-w[u]]-y;
if(!w[u])
ans[u]/=2;
}
int main()
{
n=read(),m=read();
for(int i=1;i<n;i++)
{
int x=read(),y=read();
add(x,y),add(y,x);
}
dfs1(1,0);
dfs2(1,1);
for(int i=1;i<=n;i++)
w[i]=read();
for(int i=1;i<=m;i++)
s[i]=read(),t[i]=read(),lc[i]=lca(s[i],t[i]);
for(int i=1;i<=m;i++)
{
int l=lc[i],du=de[s[i]],dv=de[t[i]],dl=de[l],dis=du+dv-2*dl;
a[s[i]].push_back(tg(du,1));
a[l].push_back(tg(du,-1));
a[t[i]].push_back(tg(dv-dis,1));
a[fa[l]].push_back(tg(dv-dis,-1));
}
dfs(1);
for(int i=1;i<=n;i++)
printf("%d ",ans[i]);
return 0;
}

bzoj 4719: [Noip2016]天天爱跑步【树上差分+dfs】的更多相关文章

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

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

  2. bzoj 4719: [Noip2016]天天爱跑步

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

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

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

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

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

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

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

  6. BZOJ 4719 [Noip2016]天天爱跑步 ——树链剖分

    一直以为自己当时是TLE了,但是再看发现居然WA? 然后把数组扩大一倍,就A掉了.QaQ 没什么好说的.一段路径分成两段考虑,上升的一段深度+时间是定值,下降的一段深度-时间是定值,然后打标记统计即可 ...

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

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

  8. 4719: [Noip2016]天天爱跑步

    Time Limit: 40 Sec Memory Limit: 512 MB Submit: 1986 Solved: 752 [Submit][Status][Discuss] Descripti ...

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

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

随机推荐

  1. Vue如何在data中正常引入图片路径

    在Vue项目中通过data设置图片路径,然后在template中引入后页面无法显示图片,浏览器控制台报错:                        刚开始以为是路径出问题了,于是绝对路径.相对路 ...

  2. sql判断以逗号分隔的字符串中是否包含某个字符串--------MYSQL中利用select查询某字段中包含以逗号分隔的字符串的记录方法

    sql判断以逗号分隔的字符串中是否包含某个字符串---------------https://blog.csdn.net/wttykj/article/details/78520933 MYSQL中利 ...

  3. [NOIP2006] 提高组 洛谷P1064 金明的预算方案

    题目描述 金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间金明自己专用的很宽敞的房间.更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎么布置,你说了算,只要不超过N元钱就行”.今 ...

  4. 莫比乌斯反演套路一--令t=pd--BZOJ2820: YY的GCD

    t<=10000组询问:有多少x,y,满足$x\epsilon [1,n],y\epsilon [1,m],(x,y)为质数$.n,m<=1e7. 首先式子列出来,f(i)--1<= ...

  5. Linux下汇编语言学习笔记11 ---

    这是17年暑假学习Linux汇编语言的笔记记录,参考书目为清华大学出版社 Jeff Duntemann著 梁晓辉译<汇编语言基于Linux环境>的书,喜欢看原版书的同学可以看<Ass ...

  6. 不同app之间activity的跳转

    关键在于指定activity的action属性 <activity android:name=".HardActivity"> <intent-filter> ...

  7. linux man 1,2,3 命令

    原文: http://blog.sina.com.cn/s/blog_969c52730101c0p7.html ------------------------------------------- ...

  8. ios网络学习------11 原生API文件上传之断点续传思路

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaHVhbmcyMDA5MzAzNTEz/font/5a6L5L2T/fontsize/400/fill/I0 ...

  9. openstack-glance-api.service start request repeated too quickly, refusing to start

    问题描写叙述 openstack J版 centos7部署 重新启动服务时起不来,日志也不报错.以glance服务为例,例如以下: # systemctl start openstack-glance ...

  10. oracle事务处理及实例演示jdbc操作批量删除

    事务 作为逻辑处理的基本单位,对于数据库操作来说由一条或者多条sql语句来构成.当然还有针对非数据库操作的,如在计算机中设置的还原点即是一个非常好的应用. 对于事务的基本性质在还有一篇中有所叙述:SQ ...