http://www.elijahqi.win/archives/1486
题目描述

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

这个游戏的地图可以看作一一棵包含

n
n个结点和

n-1
n−1条边的树, 每条边连接两个结点,且任意两个结点存在一条路径互相可达。树上结点编号为从

1
1到

n
n的连续正整数。

现在有

m
m个玩家,第

i
i个玩家的起点为

S_i
Si​,终点为

T_i
Ti​ 。每天打卡任务开始时,所有玩家在第

0
0秒同时从自己的起点出发, 以每秒跑一条边的速度, 不间断地沿着最短路径向着自己的终点跑去, 跑到终点后该玩家就算完成了打卡任务。 (由于地图是一棵树, 所以每个人的路径是唯一的)

小C想知道游戏的活跃度, 所以在每个结点上都放置了一个观察员。 在结点

j
j的观察员会选择在第

W_j
Wj​秒观察玩家, 一个玩家能被这个观察员观察到当且仅当该玩家在第

W_j
Wj​秒也理到达了结点

j
j 。 小C想知道每个观察员会观察到多少人?

注意: 我们认为一个玩家到达自己的终点后该玩家就会结束游戏, 他不能等待一 段时间后再被观察员观察到。 即对于把结点

j
j作为终点的玩家: 若他在第

W_j
Wj​秒前到达终点,则在结点

j
j的观察员不能观察到该玩家;若他正好在第

W_j
Wj​秒到达终点,则在结点

j
j的观察员可以观察到这个玩家。

输入输出格式

输入格式:
第一行有两个整数

n
n和

m
m 。其中

n
n代表树的结点数量, 同时也是观察员的数量,

m
m代表玩家的数量。

接下来

n- 1
n−1行每行两个整数

u
u和

v
v,表示结点

u
u到结点

v
v有一条边。

接下来一行

n
n个整数,其中第

j
j个整数为

W_j
Wj​ , 表示结点

j
j出现观察员的时间。

接下来

m
m行,每行两个整数

S_i
Si​,和

T_i
Ti​,表示一个玩家的起点和终点。

对于所有的数据,保证

1\leq S_i,T_i\leq n, 0\leq W_j\leq n
1≤Si​,Ti​≤n,0≤Wj​≤n 。

输出格式:
输出1行

n
n个整数,第

j
j个整数表示结点

j
j的观察员可以观察到多少人。

输入输出样例

输入样例#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
输出样例#1: 复制

2 0 0 1 1 1
输入样例#2: 复制

5 3
1 2
2 3
2 4
1 5
0 1 0 3 0
3 1
1 4
5 5
输出样例#2: 复制

1 2 1 0 1
说明

【样例1说明】

对于1号点,

W_i=0
Wi​=0,故只有起点为1号点的玩家才会被观察到,所以玩家1和玩家2被观察到,共有2人被观察到。

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

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

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

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

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

【子任务】

每个测试点的数据规模及特点如下表所示。 提示: 数据范围的个位上的数字可以帮助判断是哪一种数据类型。

【提示】

如果你的程序需要用到较大的栈空问 (这通常意味着需要较深层数的递归), 请务必仔细阅读选手日录下的文本当rumung:/stact.p″, 以了解在最终评测时栈空问的限制与在当前工作环境下调整栈空问限制的方法。

在最终评测时,调用栈占用的空间大小不会有单独的限制,但在我们的工作

环境中默认会有 8 MB 的限制。 这可能会引起函数调用层数较多时, 程序发生

栈溢出崩溃。

我们可以使用一些方法修改调用栈的大小限制。 例如, 在终端中输入下列命

令 ulimit -s 1048576

此命令的意义是,将调用栈的大小限制修改为 1 GB。

例如,在选手目录建立如下 sample.cpp 或 sample.pas

将上述源代码编译为可执行文件 sample 后,可以在终端中运行如下命令运

行该程序

./sample

如果在没有使用命令“ ulimit -s 1048576”的情况下运行该程序, sample

会因为栈溢出而崩溃; 如果使用了上述命令后运行该程序,该程序则不会崩溃。

特别地, 当你打开多个终端时, 它们并不会共享该命令, 你需要分别对它们

运行该命令。

请注意, 调用栈占用的空间会计入总空间占用中, 和程序其他部分占用的内

存共同受到内存限制。

非常妙的一道题啊

当作模拟赛的时候最多我只能想到45分

如果我们仍然每个人去考虑那么肯定是不可行的

那么我们考虑 几次搜索遍历全树然后得出答案

我们是不是考虑 当一个点x满足dep[x]+w[x]==dep[s]的时候这个路径就可以被这个观察员观察到

反过来 考虑 当我们从lca下到v的时候是不是满足dis[u,v]-w[x]=dep[u]-dep[x]这个点就可以观察到

我们考虑一条链的情况

针对一条链 我们从后往前做 我们要维护一个统计数组a[k]表示处理到当前节点从k出发的有多少条路径

然后我们倒序 做 每次找一下a[k+w[k]]的个数就是我答案的数量 然后每到之处 减去这个地方 桶内的值的a数组 即可

对于树的情况 如果lca正好可以观察到 那么我们要把lca上可以观察到的点-1 去除重复

这个思路主要和这个神犇学习的qwq

http://www.cnblogs.com/ljh2000-jump/p/6189053.html

#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
#define N 330000
#define dx 300000
inline char gc(){static char now[1<<16],*S,*T;if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;}return *S++;
}
inline int read(){int x=0;char ch=gc();while (ch<'0'||ch>'9')ch=gc();while (ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=gc();}return x;
}
struct node{int y,next;
}data[N<<1];
struct node1{int x,y,len,lca;
}qr[N];
int h[N],bin[20],fa[N][20],Log[N],n,max_d,dep[N],a[N],in[N],w[N],aa[N<<2],ans[N],num,m;
vector<int> q[N],st[N],ed[N];
void dfs(int x){for (int i=h[x];i;i=data[i].next){int y=data[i].y;if (fa[x][0]==y) continue;dep[y]=dep[x]+1;fa[y][0]=x;for (int j=1;j<=Log[dep[y]];++j) fa[y][j]=fa[fa[y][j-1]][j-1];dfs(y);}
}
void dfs1(int x){int pre;if (dep[x]+w[x]<=max_d) pre=a[w[x]+dep[x]];for (int i=h[x];i;i=data[i].next){int y=data[i].y;if (fa[x][0]==y) continue;dfs1(y);}a[dep[x]]+=in[x];if (dep[x]+w[x]<=max_d) ans[x]+=a[w[x]+dep[x]]-pre;for (int i=0;i<q[x].size();++i) a[dep[q[x][i]]]--;
}
inline int lca(int x,int y){if (dep[x]<dep[y]) swap(x,y);int dis=dep[x]-dep[y];for (int i=0;i<=Log[dis];++i) if (bin[i]&dis) x=fa[x][i];if (x==y) return x;for (int i=Log[dep[x]];~i;--i) if (fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];return fa[x][0];
}
void dfs2(int x){int pre=aa[w[x]-dep[x]+dx];for (int i=h[x];i;i=data[i].next){int y=data[i].y;if (fa[x][0]==y) continue;dfs2(y);}for (int i=0;i<st[x].size();++i) aa[st[x][i]+dx]++;//printf("%d\n",st[x][i]+dx);ans[x]+=aa[w[x]-dep[x]+dx]-pre;for (int i=0;i<ed[x].size();++i) aa[ed[x][i]+dx]--;//printf("%d\n",ed[x][i]+dx);
}
int main(){freopen("1600.in","r",stdin);n=read();m=read();Log[0]=-1;for (int i=1;i<=n;++i) Log[i]=Log[i>>1]+1;for (int i=0;i<=19;++i) bin[i]=1<<i;for (int i=1;i<n;++i){int x=read(),y=read();data[++num].y=y;data[num].next=h[x];h[x]=num;data[++num].y=x;data[num].next=h[y];h[y]=num;}for (int i=1;i<=n;++i) w[i]=read();dfs(1);for (int i=1;i<=m;++i){qr[i].x=read();in[qr[i].x]++;qr[i].y=read();qr[i].lca=lca(qr[i].x,qr[i].y);q[qr[i].lca].push_back(qr[i].x);qr[i].len=dep[qr[i].x]+dep[qr[i].y]-2*dep[qr[i].lca];}for (int i=1;i<=n;++i) max_d=max(max_d,dep[i]);//printf("%d\n",max_d);//for (int i=1;i<=n;++i) printf("%d ",dep[i]);dfs1(1);for (int i=1;i<=m;++i){st[qr[i].y].push_back(qr[i].len-dep[qr[i].y]);ed[qr[i].lca].push_back(qr[i].len-dep[qr[i].y]);}dfs2(1);for (int i=1;i<=m;++i) if (dep[qr[i].x]-dep[qr[i].lca]==w[qr[i].lca]) ans[qr[i].lca]--;for (int i=1;i<=n;++i) printf("%d ",ans[i]);return 0;
}

luogu1600天天爱跑步相关推荐

  1. NOIP2016天天爱跑步

    NOIP2016天天爱跑步 这题一看显然lca+树上差分,但是因为有w的限制不能直接加,所以考虑权值线段树合并, 每个选手的起点终点对于不同的节点的影响是不同的,这就非常麻烦了,但是可以发现无论如何他 ...

  2. Noip2016day1 天天爱跑步running

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

  3. P1600 天天爱跑步

    P1600 天天爱跑步 题目描述 详见:P1600 天天爱跑步 Solution 树上差分+LCA. Code #include<bits/stdc++.h> using namespac ...

  4. NOIP2016天天爱跑步 题解报告【lca+树上统计(桶)】

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

  5. 【洛谷】1600:天天爱跑步【LCA】【开桶】【容斥】【推式子】

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

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

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

  7. [NOIp2016]天天爱跑步 线段树合并

    [NOIp2016]天天爱跑步 LG传送门 作为一道被毒瘤出题人们玩坏了的NOIp经典题,我们先不看毒瘤的"动态爱跑步"和"天天爱仙人掌",回归一下本来的味道. ...

  8. noip2016 day1 t2 天天爱跑步

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

  9. [NOIP2016]天天爱跑步 题解(树上差分) (码长短跑的快)

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

  10. NOIP2016提高组 第一天第二题 天天爱跑步running 题解

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

最新文章

  1. ORACLE数据库系统结构
  2. django中html中图片路径怎么写,django css样式,图片路径问题解决方案
  3. 数据库开发——MySQL——存储引擎
  4. php 打开pdf文件附件,pdf里怎么链接到附件
  5. 使用CLI模板 | Visual Studio 2019(16.10)新功能试用
  6. php class variable,解决关于PHP“Undefined variable”变量未定义
  7. git 查看分支_系统掌握Git之—探索.git
  8. postgresql 先创建唯一主键 再分区_PostgreSQL 务实应用(三/5)分表复制
  9. Java J2EE中的依赖查找
  10. 完整的连接器设计手册_连接器材料使用大全
  11. How to enable/disable EWF
  12. 使用iPhone配置实用工具编辑APN设…
  13. 如何使用(稿定)设计软件无水印
  14. GO语言之LiteIDE软件的安装与使用
  15. cppcheck 自定义规则_Cppcheck 用法-编码规范
  16. 关于csdn 博客图片无法加载的问题!
  17. 游戏主机系统,破旧老电脑秒变高性能儿时复古游戏主机
  18. TLS版本及CipherSuites确认及设置
  19. [py] 统计输入字符串中的单词个数及单词的平均长度
  20. 程序员的“三十而已”

热门文章

  1. BUUCTF-CRYPTO-强网杯2019 Copperstudy
  2. 酷派5890 ROM教程
  3. 【每天学点管理学】目标管理工具——SMART法则
  4. 设置透明背景和转换图片格式的技巧
  5. 终极解决电脑缺失dll,应用程序无法正常启动0xc000007b
  6. 【Android】【MTK】MTK系统启动流程
  7. Unimodal Array
  8. 公云(3322)动态域名更新API
  9. PX4-小型固定翼滑跑起飞问题分析
  10. 现场总线CANopen设计与应用