6303 天天爱跑步 0x60「图论」例题

描述

小C同学认为跑步非常有趣,于是决定制作一款叫作《天天爱跑步》的游戏。《天天爱跑步》是一个养成类游戏,需要玩家每天按时上线,完成打卡任务。

这个游戏的地图可以看作一棵包含 n (n≤3*10^5) 个节点和 n-1 条边的树,任意两个节点存在一条路径互相可达。树上节点的编号是 1~n 之间的连续正整数。

现在有 m (m≤3*10^5) 个玩家,第 i 个玩家的起点为 S_i,终点为 T_i。每天打卡任务开始时,所有玩家在第0秒同时从自己的起点出发,以每秒跑一条边的速度,不间断地沿着最短路径向着自己的终点跑去,跑到终点后该玩家就算完成了打卡任务。因为地图是一棵树,所以每个人的路径是唯一的。

小C想知道游戏的活跃度,所以在每个节点上都放置了一个观察员。在节点 j 的观察员会选择在第 W_j 秒观察玩家,一个玩家能被这个观察员观察到当且仅当该玩家在第 W_j 秒也正好到达了节点 j。小C想知道每个观察员会观察到多少人?

注意:我们认为一个玩家到达自己的终点后,该玩家就会结束游戏,他不能等待一段时间后再被观察员观察到。即对于把节点 j 作为终点的玩家:若他在第 W_j 秒前到达终点,则在节点 j 的观察员不能观察到该玩家;若他正好在第 W_j 秒到达终点,则在节点 j 的观察员可以观察到这个玩家。

输入格式

第一行有两个整数N和M 。其中N代表树的结点数量, 同时也是观察员的数量, M代表玩家的数量。

接下来n-1 行每行两个整数U和V ,表示结点U 到结点V 有一条边。

接下来一行N 个整数,其中第个整数为Wj , 表示结点出现观察员的时间。

接下来 M行,每行两个整数Si和Ti,表示一个玩家的起点和终点。

对于所有的数据,保证 1<=Si,Ti<=N,0<=Wj<=N。

输出格式

一行 N 个整数,第 i 个整数表示结点 i 的观察员可以观察到多少人。

样例输入

样例输入1
6 3
2 3
1 2 
1 4 
4 5 
4 6 
0 2 5 1 2 3 
1 5 
1 3 
2 6
样例输入2
5 3 
1 2 
2 3 
2 4 
1 5 
0 1 0 3 0 
3 1 
1 4
5 5 

样例输出

样例输入1
2 0 0 1 1 1
样例输入2
1 2 1 0 1 

数据范围与约定

样例解释

在第一个样例中,对于1号点,W1=0,故只有起点为1号点的玩家才会被观察到,所以玩家1和玩家2被观察到,共2人被观察到。

对于2号点,没有玩家在第2秒时在此结点,共0人被观察到。

对于3号点,没有玩家在第5秒时在此结点,共0人被观察到。

对于4号点,玩家1被观察到,共1人被观察到。

对于5号点,玩家1被观察到,共1人被观察到。

对于6号点,玩家3被观察到,共1人被观察到。

来源

CCF NOIP2016 D1T2

        </article>

题解

分为两段,可以分开做:

  1. 在\(S_i\)处产生\(d[S_i]\),在\(fa[lca(S_i,T_i)]\)处减去它,在任意节点\(x\)处统计\(W[x]+d[x]\)的个数。
  2. 在\(T_i\)处产生\(d[S_i]-2*d[lca(S_i,T_i)]\),在\(lca(S_i,T_i)\)处减去它,在任意节点\(x\)处统计\(W[x]-d[x]\)的个数。

而这个用不着线段树合并,直接用在每个节点用vector存一下变动,开全局数组统计,用末值减去初值就是答案了。

时间复杂度\(O(m\log n+n)\)

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
rg T data=0,w=1;rg char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-') w=-w;
for(;isdigit(ch);ch=getchar()) data=data*10+ch-'0';
return data*w;
}
template<class T>il T read(rg T&x) {return x=read<T>();}
typedef long long ll;
using namespace std; co int N=3e5+1;
int n,m,t;
vector<int> e[N];
int fa[N][20],dep[N];
void bfs(){
t=log(n)/log(2);
queue<int> q;
dep[1]=1,q.push(1);
for(int x;q.size();){
x=q.front(),q.pop();
for(int i=0,y;i<e[x].size();++i){
if(dep[y=e[x][i]]) continue;
dep[y]=dep[x]+1,fa[y][0]=x;
for(int j=1;j<=t;++j) fa[y][j]=fa[fa[y][j-1]][j-1];
q.push(y);
}
}
}
int lca(int x,int y){
if(dep[x]>dep[y]) swap(x,y);
for(int i=t;i>=0;--i)
if(dep[fa[y][i]]>=dep[x]) y=fa[y][i];
if(x==y) return x;
for(int i=t;i>=0;--i)
if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];
return fa[x][0];
} int w[N],c1[N*2],c2[N*2],ans[N];
vector<int> a1[N],b1[N],a2[N],b2[N];
void dfs(int x){
int val1=c1[dep[x]+w[x]],val2=c2[w[x]-dep[x]+n];
for(int i=0,y;i<e[x].size();++i)
if((y=e[x][i])!=fa[x][0]) dfs(y);
for(int i=0;i<a1[x].size();++i) ++c1[a1[x][i]];
for(int i=0;i<b1[x].size();++i) --c1[b1[x][i]];
for(int i=0;i<a2[x].size();++i) ++c2[a2[x][i]+n];
for(int i=0;i<b2[x].size();++i) --c2[b2[x][i]+n];
ans[x]=c1[dep[x]+w[x]]-val1+c2[w[x]-dep[x]+n]-val2;
}
int main(){
read(n),read(m);
for(int i=1,x,y;i<n;++i){
read(x),read(y);
e[x].push_back(y),e[y].push_back(x);
}
bfs();
for(int i=1;i<=n;++i) read(w[i]);
for(int i=1,x,y,z;i<=m;++i){
read(x),read(y),z=lca(x,y);
a1[x].push_back(dep[x]),b1[fa[z][0]].push_back(dep[x]);
a2[y].push_back(dep[x]-2*dep[z]),b2[z].push_back(dep[x]-2*dep[z]);
}
dfs(1);
for(int i=1;i<=n;++i) printf("%d ",ans[i]);
return 0;
}

CH6303 天天爱跑步的更多相关文章

  1. UOJ261 【NOIP2016】天天爱跑步

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

  2. BZOJ4719 [Noip2016]天天爱跑步

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

  3. noip2016天天爱跑步

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

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

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

  5. [NOIP]2016天天爱跑步

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

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

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

  7. [NOIp 2016]天天爱跑步

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

  8. 【NOIP2016】【LCA】【树上差分】【史诗级难度】天天爱跑步

    学弟不是说要出丧题吗>>所以我就研究了1天lca又研究了1天tj然后研究了一天天天爱跑步,终于写了出来.(最后的平均用时为240ms...比学弟快了1倍...) 题意:给你颗树,然后有m个 ...

  9. 【NOIP2016】天天爱跑步

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

随机推荐

  1. Float在内存中的存储方式及IEC61131处理

    Float在内存中的存储方式及IEC61131处理 1,fp32(32bits float)类型数据在存储器中占用4Bytes存储,且遵循IEEE-754标准: 一个浮点数分三部分组成: 符号位s(1 ...

  2. Spring中的AOP实现思路

    AOP是面向切面编程,为什么在切面中写一个注解方法@Before,这个方法会在目标方法前面执行呢 基于JDK动态代理实现上面说的情况 自定义注解 @Target({ ElementType.METHO ...

  3. Pandas的基础操作(一)——矩阵表的创建及其属性

    Pandas的基础操作(一)——矩阵表的创建及其属性 (注:记得在文件开头导入import numpy as np以及import pandas as pd) import pandas as pd ...

  4. 【Linux】一步一步学Linux——初识Linux命令解析器(10)

    目录 00. 目录 01. Shell简介 02. Shell分类 03. 交互式shell和非交互式shell 04. 登录shell和非登录shell 05. Shell类型 06. 参考 00. ...

  5. Detecting GAN-generated Imagery using Color Cues

    Abstract     论文创新点:分析流行GAN网络结构得知,GAN网络生成得图片在颜色处理与真实摄像机拍摄的照片存在不同,主要表现在两方面.     实验结果:证明了两种线索能够有效区分GAN生 ...

  6. Redis学习笔记(一)— 基本命令和数据类型

    MacOs环境 Redis基本命令 启动服务:redis-server 连接服务:redis-cli -h 指定主机/IP -p 指定端口 -a 指定密码 关闭服务:先shutdown 保存数据并关闭 ...

  7. SpringCloud之Zuul网关简介、映射vs过滤配置使用

    目的: Zuul路由网关简介及基本使用 Zuul路由映射配置 Zuul请求过滤配置 Zuul路由网关简介及基本使用 Zuul简介: Zuul是从设备和网站到Netflix流应用程序后端的所有请求的前门 ...

  8. mysql_新建表:主键、外键等

    序号 命令(中文) 命令(英文呢) 解释 示例 备注 1 主键约束 primary key 不能重复,不能为空 学号 2 外键约束 foreign key 可以重复,依赖主键 学号 3 非空约束 no ...

  9. go 基本IO接口

    package main import ( "fmt" "io" "strings" ) func ReadFrom(reader io.R ...

  10. Java8系列 (三) Spliterator可分迭代器

    本文转载自 jdk8 Stream 解析2 - Spliterator分割迭代器. 概述 我们最为常见的流的产生方式是 collection.stream(), 你点开Stream()方法, 他是通过 ...