题目

小 C 同学认为跑步非常有趣,于是决定制作一款叫做《天天爱跑步》的游戏。 《天天爱跑步》是一个养成类游戏,需要玩家每天按时上线,完成打卡任务。 这个游戏的地图可以看作一棵包含 n 个结点和 n − 1 条边的树,每条边连接两个结点,且任意两个结点存在一条路径互相可达。树上结点编号为从 1 到 n 的连续正整数。 现在有 m 个玩家,第 i 个玩家的起点为 Si ,终点为 Ti 。每天打卡任务开始时,所 有玩家在第 0 秒同时从自己的起点出发,以每秒跑一条边的速度,不间断地沿着 最短 路径向着自己的终点跑去,跑到终点后该玩家就算完成了打卡任务。(由于地图是一棵树,所以每个人的路径是唯一的)

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

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

分析

假设有一条路径(x->y),最近公共祖先lca,

考虑i这个点是否能观察到这个玩家,

才成两条路径,分两种情况,

一、(x->lca)



如果要使i可以观察到,

i一定在(x->lca)上

那么deep[i]+w[i]=deep[x]。

建一个桶,

在x入栈时将deep[x]加入到桶中,

在lca退栈时,将deep[x]踢掉。

二、(lca的某个儿子且为j的祖先->y)



如果要使i可以观察到,

i一定在(lca的某个儿子且为j的祖先->y)上

那么deep[i]-w[i]=deep[y]-t(t=deep[x]+deep[y]-deep[lca]*2)。

再建一个桶,

同样

在y入栈时将deep[y]-t加入到同中,

lca的某个儿子且为j的祖先退栈时,将deep[y]-t踢掉。

因为会算重,所以将做完以i为根的子树后的值-i进栈时的值就是i的答案。

#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
using namespace std;
const int N=700005;
int deep[N],next[N],last[N],to[N],deep1[N],n,m,w[N],tot,ans[N],a[N][2],g[N][20],sum,mxd,t[N*4],t1[N*4];
int next1[N],last1[N],to1[N],tot1;
int next2[N],last2[N],to2[N],tot2;
int next3[N],last3[N],to3[N],tot3;
int next4[N],last4[N],to4[N],tot4;
int bj(int x,int y){next[++tot]=last[x];last[x]=tot;to[tot]=y;}
int bj1(int x,int y){next1[++tot1]=last1[x];last1[x]=tot1;to1[tot1]=y;}
int bj2(int x,int y){next2[++tot2]=last2[x];last2[x]=tot2;to2[tot2]=y;}
int bj3(int x,int y){next3[++tot3]=last3[x];last3[x]=tot3;to3[tot3]=y;}
int bj4(int x,int y){next4[++tot4]=last4[x];last4[x]=tot4;to4[tot4]=y;}
int dg(int x)
{
for(int i=last[x];i;i=next[i])
{
int j=to[i];
if(j!=g[x][0])
{
g[j][0]=x;
deep[j]=deep[x]+1;
dg(j);
}
}
}
int lca(int x,int y)
{
if(deep[x]>deep[y])
{
int o=x;
x=y;
y=o;
}
for(int j=log2(n);j>=0;j--)
{
if(deep[g[y][j]]>=deep[x])
y=g[y][j];
}
for(int j=log2(n);j>=0;j--)
{
if(g[y][j]!=g[x][j])
y=g[y][j],x=g[x][j];
}
if(x!=y) y=g[y][0],x=g[x][0];
return x;
}
int dg1(int x)
{
int xx=t[deep[x]+w[x]]+t1[deep[x]-w[x]+N];
for(int i=last1[x];i;i=next1[i]) t[to1[i]]++;
for(int i=last3[x];i;i=next3[i]) t1[to3[i]+N]++;
for(int i=last[x];i;i=next[i])
if(to[i]!=g[x][0]) dg1(to[i]);
ans[x]=t[deep[x]+w[x]]+t1[deep[x]-w[x]+N]-xx;
for(int i=last2[x];i;i=next2[i]) t[to2[i]]--;
for(int i=last4[x];i;i=next4[i]) t1[to4[i]+N]--;
}
int main()
{
freopen("running.in","r",stdin);
freopen("running.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=1;i<=n-1;i++)
{
int x,y;
scanf("%d%d",&x,&y);
bj(x,y);
bj(y,x);
}
for(int i=1;i<=n;i++) scanf("%d",&w[i]);
deep[1]=1;
dg(1);
for(int j=1;j<=log2(n);j++)
for(int i=1;i<=n;i++)
g[i][j]=g[g[i][j-1]][j-1];
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
int top=lca(x,y),t=deep[x]+deep[y]-2*deep[top];
if(top==x)
{
bj3(y,deep[y]-t);
bj4(x,deep[y]-t);
}
else
if(top==y)
{
bj1(x,deep[x]);
bj2(y,deep[x]);
}
else
{
bj1(x,deep[x]);
bj2(top,deep[x]);
bj3(y,deep[y]-t);
for(int j=last[top];j;j=next[j])
{
if(to[j]!=g[top][0] && lca(to[j],y)==to[j])
{
bj4(to[j],deep[y]-t);
break;
}
}
}
}
dg1(1);
for(int i=1;i<=n;i++) printf("%d ",ans[i]);
return 0;
}

【NOIP2016提高组复赛day2】天天爱跑步的更多相关文章

  1. 【题解】NOIP2016提高组 复赛

    [题解]NOIP2016提高组 复赛 传送门: 玩具谜题 \(\text{[P1563]}\) 天天爱跑步 \(\text{[P1600]}\) 换教室 \(\text{[P1850]}\) 组合数问 ...

  2. [日记&做题记录]-Noip2016提高组复赛 倒数十天

    写这篇博客的时候有点激动 为了让自己不颓 还是写写日记 存存模板 Nov.8 2016 今天早上买了两个蛋挞 吃了一个 然后就做数论(前天晚上还是想放弃数论 但是昨天被数论虐了 woc noip模拟赛 ...

  3. 【NOIP2016提高组】 Day2 T1 组合数问题

    题目传送门:https://www.luogu.org/problemnew/show/P2822                 ↓题目大意↓ 数据的极限范围:n,m≤2000,k≤21,数据组数≤ ...

  4. 破译情报-NOIP2016提高组复赛模拟试题

    [题目描述] 最近国安人员截获了一份 RB 国的秘密情报, 全文都是经过加密的,每个单 词都很长.破译人员想到先把单词化简一下,方法是把每个单词尽量取短些的前 缀,但所取的前缀不能是其他单词的前缀. ...

  5. 【NOIP2016提高组】 Day2 T2 蚯蚓

    题目传送门:https://www.luogu.org/problemnew/show/P2827 自测时被题面所误导...,题面中说逢t的倍数才输出答案,以为有什么玄妙的方法直接将m次操作变成了m/ ...

  6. NOIP2016提高组复赛C 愤怒的小鸟

    题目链接:http://uoj.ac/problem/265 题目大意: 太长了不想概括... 分析: 状压DP的模板题,把所有可能的抛物线用二进制表示,然后暴力枚举所有组合,详情见代码内注释 代码如 ...

  7. 【NOIP2016提高组】 Day2 T3 愤怒的小鸟

    题目传送门:https://www.luogu.org/problemnew/show/P2831 说个题外话:NOIP2014也有一道题叫做愤怒的小鸟. 这题自测时算错了eps,导致被卡了精度,从1 ...

  8. NOIP2016提高组解题报告

    NOIP2016提高组解题报告 更正:NOIP day1 T2天天爱跑步 解题思路见代码. NOIP2016代码整合

  9. 【题解】NOIP2016 提高组 简要题解

    [题解]NOIP2016 提高组 简要题解 玩具迷题(送分) 用异或实现 //@winlere #include<iostream> #include<cstdio> #inc ...

随机推荐

  1. P2814 家谱

    我真没什么创意了woc.. so,为什么一道水题是蓝色的???哦哦哦,水好像就是蓝色的,emmm那就不是恶意评分了嘤嘤嘤 ... 好吧实际上可能是非c党对于字符串的处理需要进行编号和结构体,会麻烦一点 ...

  2. 20191128 Spring Boot官方文档学习【目录】

    Spring Boot文档 入门 使用Spring Boot 3.1. 构建系统 3.2. 结构化代码 3.3. 配置类 3.4. 自动配置 3.5. Spring beans和依赖注入 3.6. 使 ...

  3. linux top 查看CPU命令

    top 命令主要用于查看进程的相关信息,同时它也会提供查看系统平均负载,cpu 信息和内存信息 实时监控系统资源使用情况 [root@localhost ~]$ top // 动态查看进程使用资源的情 ...

  4. Windows 下 C/C++ 多线程编程入门参考范例

    #include <windows.h> #include <iostream> using namespace std; DWORD WINAPI myThread(LPVO ...

  5. [Python3] 030 常用模块 os

    目录 os 1. os.getcwd() 2. os.chdir() 3. os.listdir() 4. os.makedir() 5. os.system() 6. os.getenv() 7. ...

  6. Java -cp命令的使用

    服务器跑程序,用到了一些Linux命令,做个简单笔记. Linux(Mac)下 java -cp .:jar包路径 主类的全限定名称     全限定名有绝对路径的意思,比如一个文件file的存放路径, ...

  7. Python 入门之 内置模块 -- collections模块

    Python 入门之 内置模块 -- collections模块 1.collections -- 基于Python自带的数据类型之上额外增加的几个数据类型 from collections ​ 在内 ...

  8. 使用elasticsearch7.3版本在一台主机上部署多个实例组建集群

    系统:centos 7.4 x64 主机ip:192.168.0.160 软件包:elasticsearch-7.3.0-linux-x86_64.tar.gz 配置步骤 vim /etc/secur ...

  9. 基于HttpRunner,解析swagger数据,快速生成接口测试框架

    使用HttpRunner默认生成的项目是这样的 命令:httprunner --startproject  项目名称 so,根据这个项目的目录结构,使用python解析swagger接口参数,可以快速 ...

  10. jstl用法 简介

    <c:choose> <c:when test="${salary <= 0}"> 太惨了. </c:when> <c:when t ...