[BZOJ 4719] 天天爱跑步
Link:
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] 天天爱跑步的更多相关文章
- bzoj 4719: [Noip2016]天天爱跑步
Description 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.?天天爱跑步?是一个养成类游戏,需要 玩家每天按时上线,完成打卡任务.这个游戏的地图可以看作一一 ...
- BZOJ 4719--天天爱跑步(LCA&差分)
4719: [Noip2016]天天爱跑步 Time Limit: 40 Sec Memory Limit: 512 MBSubmit: 1464 Solved: 490[Submit][Stat ...
- 4719: [Noip2016]天天爱跑步
Time Limit: 40 Sec Memory Limit: 512 MB Submit: 1986 Solved: 752 [Submit][Status][Discuss] Descripti ...
- BZOJ4719[NOIP2016提高组Day1T2] 天天爱跑步
#261. [NOIP2016]天天爱跑步 描述 提交 自定义测试 小C同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是一个养成类游戏,需要玩家 ...
- UOJ261 【NOIP2016】天天爱跑步
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...
- BZOJ4719 [Noip2016]天天爱跑步
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...
- noip2016天天爱跑步
题目描述 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.«天天爱跑步»是一个养成类游戏,需要玩家每天按时上线,完成打卡任务. 这个游戏的地图可以看作一一棵包含 个结点 ...
- [NOIP]2016天天爱跑步
[NOIP]2016天天爱跑步 标签: LCA 树上差分 NOIP Description 小C同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是 ...
- NOIP2016 天天爱跑步 80分暴力
https://www.luogu.org/problem/show?pid=1600 题目描述 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.«天天爱跑步»是一个养 ...
随机推荐
- oozie与sqoop的简单案例
1:拷贝模板 2:拷贝hive用的jar包 方式一: 3:编辑job.properties # # Licensed to the Apache Software Foundation (ASF) u ...
- c++刷题(3/100)数独,栈和队列
stack的基本操作 • s.size():返回栈中的元素数量 • s.empty():判断栈是否为空,返回true或false • s.push(元素):返回对栈顶部“元素”的可变(可修改)引用 • ...
- Problem 2278 YYS (FZU + java大数)
题目链接:http://acm.fzu.edu.cn/problem.php?pid=2278 题目: 题意: 有n种卡牌,每种卡牌被抽到的概率为1/n,求收齐所有卡牌的天数的期望. 思路: 易推得公 ...
- NYOJ 221 Tree (二叉树)
题目链接 描述 Little Valentine liked playing with binary trees very much. Her favorite game was constructi ...
- 2、Web基本介绍及Html语法介绍
1.1 Web基本介绍 1.web就是world wide web的缩写.称之为全球广域网,俗称www.2.我们可以将web理解为就是当前的一种互联网.对于我们来说更多的就是网站服务.3.网站我们可以 ...
- uboot1.1.6 start.s分析
.Stage1 start.S代码结构 u-boot的stage1代码通常放在start.S文件中,他用汇编语言写成,其主要代码部分如下:(1)定义入口.由于一个可执行的Image必须有一个入口点,并 ...
- 144.Binary Tree Preorder Traversal---二叉树先序、中序非递归遍历
题目链接 题目大意:返回二叉树的先序遍历list.中序见94,后序见145. 法一:普通递归遍历,只是这里多了一个list数组,所以分成了两个函数.代码如下(耗时1ms): public List&l ...
- 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 ...
- java基础4 函数
本文知识点(目录): 1.函数的概述 2.函数的格式 3.自定义函数 4.函数的特点 5.函数的应用 6.函数的重载 1.函数的概述 发现不断进行加法运算,为了提高代码的 ...
- 问候Maven3(笔记一)
第一节:Maven 简介 百度百科:Maven 官网:http://maven.apache.org/ 第二节:Maven 安装与配置 Maven 下载:http://maven.apache.org ...