洛谷$P1600$ 天天爱跑步 树上差分
正解:树上差分
解题报告:
这题还挺妙的,,,我想了半天才会$kk$
首先对一条链$S-T$,考虑先将它拆成$S-LCA$和$LCA-T$,分别做.因为总体上来说差不多接下来我就只港$S-LCA$的做法了$QwQ$
考虑对于一个观察点$j$,若要观察到玩家$i$,则有$dep_j+w_j=dep_i$.发现现在就只用统计$j$的子树内所有起点深度等于$dep_j+w_j$的就行.
显然考虑树上差分呗.就开个桶记$dep_i$,对每条路径在$S$处给$dep_S$+1,到$LCA$处给$dep_S-1$,然后在每个观察点答案就直接查$t_{dep_j+w_j}$就完事$QwQ$.
然后$LCA-T$差不多?就表达式变下,细节注意下,$over$
嗷然后其实这里$LCA$是算重了的嘛,最后把重复的贡献减去就好$QwQ$
#include<bits/stdc++.h>
using namespace std;
#define il inline
#define gc getchar()
#define t(i) edge[i].to
#define w(i) edge[i].wei
#define fy(i) edge[i].fy
#define ri register int
#define rb register bool
#define rc register char
#define rp(i,x,y) for(ri i=x;i<=y;++i)
#define my(i,x,y) for(ri i=x;i>=y;--i)
#define e(i,x) for(ri i=head[x];i;i=edge[i].nxt) const int N=600000+10;
int ed_cnt,head[N],n,m,fa[N][20],w[N],dep[N],mx,tz[N<<1],as[N],val[N];
struct ed{int to,nxt,wei,fy;}edge[N<<1];
struct node{int fr,to,lca,len;}nod[N];
vector<int>V1[N],V2[N],V3[N]; il int read()
{
rc ch=gc;ri x=0;rb y=1;
while(ch!='-' && (ch>'9' || ch<'0'))ch=gc;
if(ch=='-')ch=gc,y=0;
while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^'0'),ch=gc;
return y?x:-x;
}
il void ad(ri x,ri y){edge[++ed_cnt]=(ed){x,head[y]};head[y]=ed_cnt;}
void dfs(ri x){e(i,x)if(!dep[t(i)])dep[t(i)]=dep[x]+1,fa[t(i)][0]=x,dfs(t(i));}
il int lca(ri x,ri y)
{
if(dep[x]<dep[y])swap(x,y);my(i,19,0)if(dep[fa[x][i]]>=dep[y])x=fa[x][i];if(x==y)return x;
my(i,19,0)if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];;return fa[x][0];
}
void dfs1(ri x)
{
ri tmp=w[x]+dep[x],t;if(tmp<=mx)t=tz[tmp];e(i,x)if(t(i)!=fa[x][0])dfs1(t(i));
tz[dep[x]]+=val[x];if(tmp<=mx)as[x]=tz[tmp]-t;ri sz=V1[x].size();rp(i,0,sz-1)--tz[dep[V1[x][i]]];
}
void dfs2(ri x)
{
ri tmp=dep[x]-w[x]+N,t=tz[tmp];e(i,x)if(t(i)!=fa[x][0])dfs2(t(i));
ri sz=V2[x].size();rp(i,0,sz-1)++tz[V2[x][i]];as[x]+=tz[tmp]-t;sz=V3[x].size();rp(i,0,sz-1)--tz[V3[x][i]];
}
il void pre()
{
n=read();m=read();rp(i,1,n-1){ri x=read(),y=read();ad(x,y);ad(y,x);ad(x,y);}rp(i,1,n)w[i]=read();
dep[1]=1;dfs(1);rp(i,1,19)rp(j,1,n)fa[j][i]=fa[fa[j][i-1]][i-1];rp(i,1,n)mx=max(mx,dep[i]);
}
il void work()
{
rp(i,1,m)
{
ri x=read(),y=read(),lcaa=lca(x,y);nod[i]=(node){x,y,lcaa,dep[x]+dep[y]-(dep[lcaa]<<1)};
V1[lcaa].push_back(x);++val[x];
}
dfs1(1);
rp(i,1,m){ri tmp=dep[nod[i].to]-nod[i].len+N;V2[nod[i].to].push_back(tmp),V3[nod[i].lca].push_back(tmp);}
memset(tz,0,sizeof(tz));dfs2(1);
rp(i,1,m)if(dep[nod[i].fr]-dep[nod[i].lca]==w[nod[i].lca])--as[nod[i].lca];rp(i,1,n)printf("%d ",as[i]);
} int main()
{
freopen("1600.in","r",stdin);freopen("1600.out","w",stdout);
pre();work();
return 0;
}
出于一些不知名原因我要把数组开大一倍不然会$WA$第13个点$kk$
洛谷$P1600$ 天天爱跑步 树上差分的更多相关文章
- 洛谷P1600 天天爱跑步——树上差分
题目:https://www.luogu.org/problemnew/show/P1600 看博客:https://blog.csdn.net/clove_unique/article/detail ...
- 洛谷 1600 (NOIp2016) 天天爱跑步——树上差分
题目:https://www.luogu.org/problemnew/show/P1600 看TJ:https://blog.csdn.net/clove_unique/article/detail ...
- NOIP2016 Day1 T2 天天爱跑步(树上差分,LCA)
原文链接 原题链接 题目描述 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是一个养成类游戏,需要玩家每天按时上线,完成打卡任务. 这个游戏 ...
- NOIP2016 天天爱跑步 (树上差分+dfs)
题目大意:给你一颗树,树上每个点都有一个观察员,他们仅会在 w[i] 时刻出现,观察正在跑步的玩家 一共有m个玩家,他们分别从节点 s[i] 同时出发,以每秒跑一条边的速度,沿着到 t[i] 的唯一路 ...
- [NOIP2016]天天爱跑步(树上差分+线段树合并)
将每个人跑步的路径拆分成x->lca,lca->y两条路径分别考虑: 对于在点i的观察点,这个人(s->t)能被观察到的充要条件为: 1.直向上的路径:w[i]=dep[s]-dep ...
- NOIP2016 天天爱跑步 - 树上差分
传送门 题目分析: 一年前还是个傻子的时候居然直接放弃了这题. 首先列出两个方程:如果i节点的观察员能够观察到由s->t的那个人,那么: \[dep[s] - dep[i] = w[i], de ...
- 洛谷 P2680 运输计划-二分+树上差分(边权覆盖)
P2680 运输计划 题目背景 公元 20442044 年,人类进入了宇宙纪元. 题目描述 公元20442044 年,人类进入了宇宙纪元. L 国有 nn 个星球,还有 n-1n−1 条双向航道,每条 ...
- 洛谷P1600 天天爱跑步(线段树合并)
小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是一个养成类游戏,需要玩家每天按时上线,完成打卡任务. 这个游戏的地图可以看作一一棵包含 nn ...
- BZOJ 4719--天天爱跑步(LCA&差分)
4719: [Noip2016]天天爱跑步 Time Limit: 40 Sec Memory Limit: 512 MBSubmit: 1464 Solved: 490[Submit][Stat ...
随机推荐
- IDEA使用中文api鼠标提示的设置
最近都在用IDEA来练习,发现有的方面确实比eclipse好用,eclipse里面可添加中文的API 提示,对初期的我帮助很大,但是IDEA却没有找到添加的地方,一直以来还以为不支持这个功能,比较遗憾 ...
- APICloud ajax请求api数据问题
云编译开启全局加密的情况下,请务必使用api.ajax,避免使用JQ等框架的ajax,否则将引起请求失败.官网API说明链接 还要就是要注意用$.ajax请求数据时会出现的同源策略问题.
- mysql数据库之windows版本
安装 第一步:打开网址,http://www.mysql.com.点击downloads之后跳转到http://www.mysql.com/downloads/选择Community选项 第二步:按 ...
- Java容易搞错的知识点
一.关于Switch 代码: Java代码 1 public class TestSwitch { 2 public static void main(Stri ...
- iptables 规则(Rules)
iptables的每一条规则(rule),都是由两部分组成的,第一部分包含一或多个「过滤条件」其作用是检查包是否符合处理条件(所有条件都必须成立才算数) :第而部分称为「目标」,用於決定如何处置符合条 ...
- win10如何关闭计算机设备和驱动器非硬盘图标
按win键+R,打开注册表regedit,找到这个路径: HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\My ...
- hdu 4179 Difficult Routes (SP)
Problem - 4179 坑了我一个晚上的SP题. 题意是,给出若干空间中的点,给出其中某些点之间是有直线线段路径相连的.要求求出一条从s开始到t结束的路径,它的难度是d.难度的计算是空间线段两点 ...
- 深入Java线程管理(三):线程同步
一. 引入同步: 有一个很经典的案例,即银行取款问题.我们可以先看下银行取款的基本流程: 1)用户输入账户.密码,系统判断用户的账户.密码是否匹配. 2)用户输入取款金额. 3)系统判断账户金额是否大 ...
- dotnet 设计规范 · 抽象定义
严格来说,只有一个类被其他的类继承,那么这个类就是基类.在很多时候,基类的定义是提供足够的抽象和通用方法和属性.默认实现.在继承关系中,基类定义在上层抽象和底层自定义之间. 他们充当抽象实现的实现帮助 ...
- LCA (最近公共祖先)倍增做法 —— O(nlogn)预处理 O(logn)(在线)查询
pa[a][j] 表示 a 结点的 2^j倍祖先(j = 0时 为直接父亲,j = 1时为父亲的父亲……) 1.首先预处理出所有结点的深度值dep和父亲结点 void dfs(int u, int f ...