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. oozie与sqoop的简单案例

    1:拷贝模板 2:拷贝hive用的jar包 方式一: 3:编辑job.properties # # Licensed to the Apache Software Foundation (ASF) u ...

  2. c++刷题(3/100)数独,栈和队列

    stack的基本操作 • s.size():返回栈中的元素数量 • s.empty():判断栈是否为空,返回true或false • s.push(元素):返回对栈顶部“元素”的可变(可修改)引用 • ...

  3. Problem 2278 YYS (FZU + java大数)

    题目链接:http://acm.fzu.edu.cn/problem.php?pid=2278 题目: 题意: 有n种卡牌,每种卡牌被抽到的概率为1/n,求收齐所有卡牌的天数的期望. 思路: 易推得公 ...

  4. NYOJ 221 Tree (二叉树)

    题目链接 描述 Little Valentine liked playing with binary trees very much. Her favorite game was constructi ...

  5. 2、Web基本介绍及Html语法介绍

    1.1 Web基本介绍 1.web就是world wide web的缩写.称之为全球广域网,俗称www.2.我们可以将web理解为就是当前的一种互联网.对于我们来说更多的就是网站服务.3.网站我们可以 ...

  6. uboot1.1.6 start.s分析

    .Stage1 start.S代码结构 u-boot的stage1代码通常放在start.S文件中,他用汇编语言写成,其主要代码部分如下:(1)定义入口.由于一个可执行的Image必须有一个入口点,并 ...

  7. 144.Binary Tree Preorder Traversal---二叉树先序、中序非递归遍历

    题目链接 题目大意:返回二叉树的先序遍历list.中序见94,后序见145. 法一:普通递归遍历,只是这里多了一个list数组,所以分成了两个函数.代码如下(耗时1ms): public List&l ...

  8. Django 1.10文档中文版Part1

    目录 第一章.Django1.10文档组成结构1.1 获取帮助1.2 文档的组织形式1.3 第一步1.4 模型层1.5 视图层1.6 模板层1.7 表单1.8 开发流程1.9 admin站点1.10 ...

  9. java基础4 函数

    本文知识点(目录): 1.函数的概述    2.函数的格式    3.自定义函数    4.函数的特点    5.函数的应用    6.函数的重载 1.函数的概述 发现不断进行加法运算,为了提高代码的 ...

  10. 问候Maven3(笔记一)

    第一节:Maven 简介 百度百科:Maven 官网:http://maven.apache.org/ 第二节:Maven 安装与配置 Maven 下载:http://maven.apache.org ...