Link:

BZOJ 4719 传送门

Solution:

感觉求LCA又有了新姿势啊:$Tarjan$离线$O(n+m)$

每次递归返回时将子树和父节点合并,如果询问节点已访问过则LCA就是已合并的最高节点

这题部分分提示非常多啊

首先要将路径拆为$(S,LCA),(LCA,T)$

发现如果$(S,LCA)$能对点$x$产生贡献要满足$w[x]+dep[x]=dep[S]$

而$(LCA,T)$能对点$x$产生贡献要满足$dep[x]-w[x]=dep[T]-len$

这样用$cnt$数组维护等式右边的$dep[S]$和$dep[T]-len$的值有多少个就能快速得出有几条路径满足条件

于是可以在路径起点加入该路径特征值并在路径末尾将其消除即可

注意:

1、$LCA$处可能算了两遍,最后要逐一判断

2、要在刚进入该点时记录当前$cnt[w[x]+dep[x]]$的值否则可能会将其它子树中未走完的路径计算在内

3、此题需要从下往上统计答案,因此路径起点都要设置为深度较大的,否则不好消除不经过该点路径的贡献

Code:

#include <bits/stdc++.h>

using namespace std;
#define X first
#define Y second
#define pb push_back
typedef double db;
typedef long long ll;
typedef pair<int,int> P;
const int MAXN=1e6+,ADD=3e5;
int vis[MAXN],f[MAXN],st[MAXN];
int n,q,x,y,w[MAXN],res[MAXN],cnt[MAXN],head[MAXN],dep[MAXN],tot; vector<P> par[MAXN];
vector<int> in[MAXN],out[MAXN];
struct edge{int nxt,to;}e[MAXN<<];
struct Query{int x,y,lca;}qry[MAXN]; void add(int x,int y)
{e[++tot]=(edge){head[x],y};head[x]=tot;}
int find(int x)
{return f[x]==x?x:f[x]=find(f[x]);}
void tarjan(int x,int anc)
{
vis[x]=;f[x]=x;
for(int i=;i<par[x].size();i++)
if(vis[par[x][i].X]) qry[par[x][i].Y].lca=find(par[x][i].X);
for(int i=head[x];i;i=e[i].nxt)
if(e[i].to!=anc)
{
dep[e[i].to]=dep[x]+;
tarjan(e[i].to,x);f[e[i].to]=x;
}
}
void dfs1(int x,int anc)
{
int cur=cnt[w[x]+dep[x]];
for(int i=head[x];i;i=e[i].nxt)
if(e[i].to!=anc) dfs1(e[i].to,x);
cnt[dep[x]]+=st[x];
res[x]+=cnt[w[x]+dep[x]]-cur;
for(int i=;i<out[x].size();i++) cnt[out[x][i]]--;
}
void dfs2(int x,int anc)
{
int cur=cnt[ADD-w[x]+dep[x]];
for(int i=head[x];i;i=e[i].nxt)
if(e[i].to!=anc) dfs2(e[i].to,x);
//都要看成从底向上的路径
for(int i=;i<in[x].size();i++) cnt[in[x][i]]++;
res[x]+=cnt[ADD-w[x]+dep[x]]-cur;
for(int i=;i<out[x].size();i++) cnt[out[x][i]]--;
} int main()
{
scanf("%d%d",&n,&q);
for(int i=;i<n;i++)
scanf("%d%d",&x,&y),add(x,y),add(y,x);
for(int i=;i<=n;i++) scanf("%d",&w[i]);
for(int i=;i<=q;i++)
{
scanf("%d%d",&x,&y);
qry[i].x=x,qry[i].y=y;
par[x].pb(P(y,i));par[y].pb(P(x,i));
}
tarjan(,); for(int i=;i<=q;i++)
out[qry[i].lca].pb(dep[qry[i].x]),st[qry[i].x]++;
dfs1(,);
memset(cnt,,sizeof(cnt));
for(int i=;i<=n;i++) out[i].clear();
for(int i=;i<=q;i++)
{
int len=dep[qry[i].x]+dep[qry[i].y]-*dep[qry[i].lca];
in[qry[i].y].pb(ADD+dep[qry[i].y]-len);
out[qry[i].lca].pb(ADD+dep[qry[i].y]-len);
}
dfs2(,);
for(int i=;i<=q;i++)
if(dep[qry[i].x]-dep[qry[i].lca]==w[qry[i].lca])
res[qry[i].lca]--;
for(int i=;i<=n;i++)
printf("%d ",res[i]);
return ;
}

[BZOJ 4719] 天天爱跑步的更多相关文章

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

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

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

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

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

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

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

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

  5. UOJ261 【NOIP2016】天天爱跑步

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...

  6. BZOJ4719 [Noip2016]天天爱跑步

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...

  7. noip2016天天爱跑步

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

  8. [NOIP]2016天天爱跑步

    [NOIP]2016天天爱跑步 标签: LCA 树上差分 NOIP Description 小C同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是 ...

  9. NOIP2016 天天爱跑步 80分暴力

    https://www.luogu.org/problem/show?pid=1600 题目描述 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.«天天爱跑步»是一个养 ...

随机推荐

  1. python 输出 a+b

    AC代码: 单组输入: s=input().split() print(int(s[0])+int(s[1]))

  2. Linux中查看CPU信息 (转)

    cat /proc/cpuinfo中的信息 processor       逻辑处理器的id. physical id    物理封装的处理器的id. core id        每个核心的id. ...

  3. 记点事! oracle 调用外部命令

    oracle执行系统命令   测试成功环境:windows XP+oracle 10g.window 2008 R2 + 11g   代码如下: www.2cto.com   Sql代码   crea ...

  4. NTP详解-转

    网管实战:Linux时间服务器配置 [IT168 专稿]目前计算机网络中各主机和服务器等网络设备的时间基本处于无序的状态.随着计算机网络应用的不断涌现,计算机的时间同步问题成为愈来愈重要的事情.以Un ...

  5. CRM 业务

    1. 创建CRM项目 引入插件 创建数据库 from django.db import models from django.db import models class Department(mod ...

  6. 用 python 来操作 docx, xlsx 格式文件(二)(使用 docx 库操作 docx 格式文件

    docx 库 文章结构: 一.docx 基本用,创建 docx 文件并添加数据 二.深入理解文本格式(format),并设置所格式属性(attribute) 三.深入理解样式(styles),以及如何 ...

  7. SG函数(转自百度百科)

    给定一个有向无环图和一个起始顶点上的一枚棋子,两名选手交替的将这枚棋子沿有向边进行移动,无法移 动者判负.事实上,这个游戏可以认为是所有Impartial Combinatorial Games的抽象 ...

  8. Adding Completion to (interactive)

      Adding Completion to (interactive) Author: Tubo Question: Is there any way to add my own completio ...

  9. 关于wordpress插件WP SMTP的邮箱设置

     花了两天的时间把邮箱设置好了,把大概的步骤写下,放一下查到的资料. 1.去域名服务商那里添加MX记录      如下图的MX      2.测试主机是否禁用了mail()函数      参考链接wo ...

  10. AC日记——小A和uim之大逃离 II 洛谷七月月赛

    小A和uim之大逃离 II 思路: spfa: 代码: #include <bits/stdc++.h> using namespace std; #define INF 0x3f3f3f ...