NOIP2016 天天爱跑步(线段树/桶)
题目描述
小c同学认为跑步非常有趣,于是决定制作一款叫做《天天爱跑步》的游戏。天天爱跑步是一个养成类游戏,需要 玩家每天按时上线,完成打卡任务。
这个游戏的地图可以看作一一棵包含 N个结点和N-1 条边的树, 每条边连接两个结点,且任意两个结点存在一条路径互相可达。树上结点编号为从1到N的连续正整数。
现在有个玩家,第个玩家的 起点为Si ,终点为Ti 。每天打卡任务开始时,所有玩家在第0秒同时从自己的起点出发, 以每秒跑一条边的速度, 不间断地沿着最短路径向着自己的终点跑去, 跑到终点后该玩家就算完成了打卡任务。 (由于地图是一棵树, 所以 每个人的路径是唯一的)
小C想知道游戏的活跃度, 所以在每个结点上都放置了一个观察员。 在结点的观察员会选 择在第Wj秒观察玩家, 一个玩家能被这个观察员观察到当且仅当该玩家在第Wj秒也正好到达了结点J 。 小C想知道 每个观察员会观察到多少人?
注意: 我们认为一个玩家到达自己的终点后该玩家就会结束游戏, 他不能等待一 段时 间后再被观察员观察到。 即对于把结点J作为终点的玩家: 若他在第Wj秒重到达终点,则在结点J的观察员不能观察 到该玩家;若他正好在第Wj秒到达终点,则在结点的观察员可以观察到这个玩家。
输入格式
第一行有两个整数N和M 。其中N代表树的结点数量, 同时也是观察员的数量, M代表玩家的数量。
接下来n-1 行每行两个整数U和V ,表示结点U 到结点V 有一条边。
接下来一行N 个整数,其中第个整数为Wj , 表示结点出现观察员的时间。
接下来 M行,每行两个整数Si和Ti,表示一个玩家的起点和终点。
对于所有的数据,保证 。1<=Si,Ti<=N,0<=Wj<=N
输出格式
输出1行N 个整数,第j个整数表示结点j的观察员可以观察到多少人。
解题思路:
方法一:线段树+树链剖分
首先,我们考虑什么样的玩家可以被看到,那么就是说什么时候玩家到某个节点。
设玩家初始时的位置深度为d。
大概是这样的,如果玩家在向上走时,会在0时刻走到路径上d深度的点,在1时刻走到d-1深度的点,2时刻走到d-2是深度的点。
那么在向上走的过程中,所经过点上的观察员只要使等式(w+deep)=d成立,就能看见玩家。
同样的在玩家向下走的时候也有类似的结论,就是只要玩家的(d-2*路径上lca的deep)=(w-deep)就能看见。
那么我们开线段树存就好了。
对于每个深度开两棵线段树分别记录向下走的和向上走的某个节点观察的值,也就是说在每一个玩家的d上的线段树对于每个玩家经历的点上统一+1。
也就是说树链上+1,这样只要单点查询就可以了。
树链上+1,使用树链剖分就好了^_^
线段树占很大空间动态开点就好了
还有对于一些深度较浅的点我们发现最终的向下行走的索引可能为负,所以对于向下走的线段树索引统一加上3e5
大概就是这样了^_^
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=(int)(3e5);
const int T=(int)();
struct pnt{
int w;
int hd;
int dp;
int fa;
int wgt;
int mxs;
int ind;
int top;
}p[N];
struct ent{
int twd;
int lst;
}e[N*];
struct sgt{
int ls;
int rs;
int vls;
}tr[T];
int cnt;
int siz;
int dnt;
int n,m;
int rtu[N*],rtd[N*];
int sta[N],fin[N];
void ade(int f,int t)
{
cnt++;
e[cnt].twd=t;
e[cnt].lst=p[f].hd;
p[f].hd=cnt;
}
void Tr_pushdown(int spc)
{
if(tr[spc].ls)
tr[tr[spc].ls].vls+=tr[spc].vls;
if(tr[spc].rs)
tr[tr[spc].rs].vls+=tr[spc].vls;
tr[spc].vls=;
}
void Tr_build(int &spc,int l,int r,int plc)
{
if(!spc)
spc=++siz;
if(l==r)
return ;
int mid=(l+r)/;
if(plc<=mid)
Tr_build(tr[spc].ls,l,mid,plc);
else
Tr_build(tr[spc].rs,mid+,r,plc);
} void Tr_add(int ll,int rr,int l,int r,int spc,int v)
{
if(!spc)
return ;
if(ll>r||l>rr)
return ;
if(ll<=l&&rr>=r)
{
tr[spc].vls+=v;
return ;
}
int mid=(l+r)/;
Tr_add(ll,rr,l,mid,tr[spc].ls,v);
Tr_add(ll,rr,mid+,r,tr[spc].rs,v);
return ;
}
int Tr_val(int plc,int spc,int l,int r)
{
if(!spc)
return ;
if(l==r)
return tr[spc].vls;
Tr_pushdown(spc);
int mid=(l+r)/;
if(plc<=mid)
return Tr_val(plc,tr[spc].ls,l,mid);
else
return Tr_val(plc,tr[spc].rs,mid+,r);
}
void Basic_dfs(int x,int f)
{
p[x].fa=f;
p[x].dp=p[f].dp+;
p[x].wgt=;
int maxs=;
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(to==f)
continue;
Basic_dfs(to,x);
p[x].wgt+=p[to].wgt;
if(maxs<p[to].wgt)
{
maxs=p[to].wgt;
p[x].mxs=to;
}
}
}
void Build_dfs(int x,int tp)
{
if(!x)
return ;
p[x].ind=++dnt;
p[x].top=tp;
Tr_build(rtu[p[x].dp+p[x].w],,n,dnt);
Tr_build(rtd[p[x].w-p[x].dp+N],,n,dnt);
Build_dfs(p[x].mxs,tp);
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(p[to].ind)
continue;
Build_dfs(to,to);
}
}
int LCA(int x,int y)
{
while(p[x].top!=p[y].top)
{
if(p[p[x].top].dp<p[p[y].top].dp)
swap(x,y);
x=p[p[x].top].fa;
}
if(p[x].dp>p[y].dp)
swap(x,y);
return x;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<n;i++)
{
int x,y;
scanf("%d%d",&x,&y);
ade(x,y);
ade(y,x);
}
for(int i=;i<=n;i++)
scanf("%d",&p[i].w);
for(int i=;i<=m;i++)
scanf("%d%d",&sta[i],&fin[i]);
Basic_dfs(,);
Build_dfs(,);
for(int i=;i<=m;i++)
{
int f=LCA(sta[i],fin[i]);
int x=sta[i];
int rt=p[sta[i]].dp;
while(p[x].top!=p[f].top)
{
Tr_add(p[p[x].top].ind,p[x].ind,,n,rtu[rt],);
x=p[p[x].top].fa;
}
Tr_add(p[f].ind,p[x].ind,,n,rtu[rt],);
Tr_add(p[f].ind,p[f].ind,,n,rtu[rt],-);
x=fin[i];
rt=N+p[sta[i]].dp-*p[f].dp;
while(p[x].top!=p[f].top)
{
Tr_add(p[p[x].top].ind,p[x].ind,,n,rtd[rt],);
x=p[p[x].top].fa;
}
Tr_add(p[f].ind,p[x].ind,,n,rtd[rt],);
}
for(int i=;i<=n;i++)
{
int dowsid=Tr_val(p[i].ind,rtd[N+p[i].w-p[i].dp],,n);
int upsid=Tr_val(p[i].ind,rtu[p[i].dp+p[i].w],,n);
printf("%d ",dowsid+upsid);
}
return ;
}
NOIP2016 天天爱跑步(线段树/桶)的更多相关文章
- [NOIp2016]天天爱跑步 线段树合并
[NOIp2016]天天爱跑步 LG传送门 作为一道被毒瘤出题人们玩坏了的NOIp经典题,我们先不看毒瘤的"动态爱跑步"和"天天爱仙人掌",回归一下本来的味道. ...
- NOIP2016 天天爱跑步 线段树合并_桶_思维题
竟然独自想出来了,好开心 Code: #include<bits/stdc++.h> #define setIO(s) freopen(s".in","r&q ...
- 2018.08.09 bzoj4719: [Noip2016]天天爱跑步(树链剖分)
传送门 话说开始上文化课之后写题时间好少啊. 这道题将一个人的跑步路线拆成s->lca,lca->t,然后对于第一段上坡路径要经过的点,当前这个人能对它产生贡献当且仅当dep[s]-dep ...
- [Noip2016]天天爱跑步 LCA+DFS
[Noip2016]天天爱跑步 Description 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.?天天爱跑步?是一个养成类游戏,需要玩家每天按时上线,完成打卡任 ...
- 【LG1600】[NOIP2016]天天爱跑步
[LG1600][NOIP2016]天天爱跑步 题面 洛谷 题解 考虑一条路径\(S\rightarrow T\)是如何给一个观测点\(x\)造成贡献的, 一种是从\(x\)的子树内出来,另外一种是从 ...
- [NOIP2016]天天爱跑步(树上差分+线段树合并)
将每个人跑步的路径拆分成x->lca,lca->y两条路径分别考虑: 对于在点i的观察点,这个人(s->t)能被观察到的充要条件为: 1.直向上的路径:w[i]=dep[s]-dep ...
- 【bzoj4719】[Noip2016]天天爱跑步 权值线段树合并
题目描述 给出一棵n个点的树,以及m次操作,每次操作从起点向终点以每秒一条边的速度移动(初始时刻为0),最后对于每个点询问有多少次操作在经过该点的时刻为某值. 输入 第一行有两个整数N和M .其中N代 ...
- BZOJ4719 NOIP2016天天爱跑步(线段树合并)
线段树合并的话这个noip最难题就是个裸题了. 注意merge最后return x,以及如果需要区间查询的话这里还需要up,无数次死于这里. #include<iostream> #inc ...
- NOIP2016天天爱跑步 题解报告【lca+树上统计(桶)】
题目描述 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.«天天爱跑步»是一个养成类游戏,需要玩家每天按时上线,完成打卡任务. 这个游戏的地图可以看作一一棵包含 nn个 ...
随机推荐
- CO-PRIME(初探 莫比乌斯)NYOJ1066(经典)gcd(a,b)=1
CO-PRIME 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描写叙述 This problem is so easy! Can you solve it? You are ...
- JAVA线程队列BlockingQueue
JAVA线程队列BlockingQueue 介绍 BlockingQueue阻塞队列,顾名思义,首先它是一个队列,通过一个共享的队列,可以使得数据由队列的一端输入,从另外一端输出. 常用的队列主要有以 ...
- 实测Untangle - Linux下的安全网关
UntangleGateway是一个Linux下开源的的网关模块,支持垃圾过滤.URL阻截.反病毒蠕虫等多种功能,其实他的功能还远不止这些,经过一段时间研究本人特制作本视频供大家参考. 本文出自 &q ...
- eq3
然而一旦美国经济进入持续复苏,美联储必将逐步退出量化宽松和逐渐收紧银根,美国联邦基金利率和银行同业间拆借利率将会上升.这将使美元升值,并使部分套利交易平仓.而一旦美元企稳走强,国债利率上扬,大宗商品价 ...
- java command not found
INSTALLATION PROCEDURE ON RASPBERRY PI The remaining steps should be performed directly on the conso ...
- 玲珑杯 Round #18 A -- 计算几何你瞎暴力
因为坐标都在1-10之间,因此可暴力求解 #include <iostream> #include <cstdio> #include <cstring> #inc ...
- JAVA文件写入FileWriter
JAVA文件写入FileWriter 导包import java.io.FileWriter创建构造方法public FileWrite(String filename),参数是文件的路径及文件名(默 ...
- web——前后端通信
前端向后台传输数据: 传输方法:post get 区别: (1)get:用于从服务器获取数据,将参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看 ...
- HDU——T 1166 敌兵布阵
http://acm.hdu.edu.cn/showproblem.php?pid=1166 Time Limit: 2000/1000 MS (Java/Others) Memory Limi ...
- 洛谷 P1900 自我数
P1900 自我数 题目描述 在1949年印度数学家D. R. Daprekar发现了一类称作Self-Numbers的数.对于每一个正整数n,我们定义d(n)为n加上它每一位数字的和.例如,d(75 ...