洛谷P2982 [USACO10FEB]慢下来Slowing down(线段树 DFS序 区间增减 单点查询)

To 洛谷.2982 慢下来Slowing down

题目描述

Every day each of Farmer John's N (1 <= N <= 100,000) cows conveniently numbered 1..N move from the barn to her private pasture. The pastures are organized as a tree, with the barn being on pasture 1. Exactly N-1 cow unidirectional paths connect the pastures; directly connected pastures have exactly one path. Path i connects pastures A_i and B_i (1 <= A_i <= N; 1 <= B_i <= N).

Cow i has a private pasture P_i (1 <= P_i <= N). The barn's small door lets only one cow exit at a time; and the patient cows wait until their predecessor arrives at her private pasture. First cow 1 exits and moves to pasture P_1. Then cow 2 exits and goes to pasture P_2, and so on.

While cow i walks to P_i she might or might not pass through a pasture that already contains an eating cow. When a cow is present in a pasture, cow i walks slower than usual to prevent annoying her friend.


Consider the following pasture network, where the number between
parentheses indicates the pastures' owner. 1 (3)
/ \
(1) 4 3 (5)
/ \
(2) 2 5 (4) First, cow 1 walks to her pasture: 1 (3)
/ \
[1] 4* 3 (5)
/ \
(2) 2 5 (4) When cow 2 moves to her pasture, she first passes into the barn's
pasture, pasture 1. Then she sneaks around cow 1 in pasture 4 before
arriving at her own pasture. 1 (3)
/ \
[1] 4* 3 (5)
/ \
[2] 2* 5 (4) Cow 3 doesn't get far at all -- she lounges in the barn's pasture, #1. 1* [3]
/ \
[1] 4* 3 (5)
/ \
[2] 2* 5 (4) Cow 4 must slow for pasture 1 and 4 on her way to pasture 5: 1* [3]
/ \
[1] 4* 3 (5)
/ \
[2] 2* 5* [4] Cow 5 slows for cow 3 in pasture 1 and then enters her own private pasture: 1* [3]
/ \
[1] 4* 3*[5]
/ \
[2] 2* 5* [4]

FJ would like to know how many times each cow has to slow down.

每天Farmer John的N头奶牛(1 <= N <= 100000,编号1…N)从粮仓走向他的自己的牧场。牧场构成了一棵树,粮仓在1号牧场。恰好有N-1条道路直接连接着牧场,使得牧场之间都恰好有一条路径相连。第i条路连接着A_i,B_i,(1 <= A_i <= N; 1 <= B_i <= N)。 奶牛们每人有一个私人牧场P_i (1 <= P_i <= N)。粮仓的门每次只能让一只奶牛离开。耐心的奶牛们会等到他们的前面的朋友们到达了自己的私人牧场后才离开。首先奶牛1离开,前往P_1;然后是奶牛2,以此类推。

当奶牛i走向牧场P_i时候,他可能会经过正在吃草的同伴旁。当路过已经有奶牛的牧场时,奶牛i会放慢自己的速度,防止打扰他的朋友。

FJ想要知道奶牛们总共要放慢多少次速度。

输入输出格式

输入格式:

Line 1: Line 1 contains a single integer: N

Lines 2..N: Line i+1 contains two space-separated integers: A_i and B_i

Lines N+1..N+N: line N+i contains a single integer: P_i

输出格式:

Lines 1..N: Line i contains the number of times cow i has to slow down.

输入输出样例

输入样例#1:

5
1 4
5 4
1 3
2 4
4
2
1
5
3

输出样例#1:

0
1
0
2
1

代码:

 #include<cstdio>
#include<cctype>
using namespace std;
const int N=; int n,ENum,cnt,H[N<<],Sum[N<<],Dfn[N],Size[N];
struct Edge
{
int to,nxt;
}e[N<<]; void read(int &now)
{
now=;char c=getchar();
for(;!isdigit(c);c=getchar());
for(;isdigit(c);c=getchar())
now=(now<<)+(now<<)+c-'';
} void AddEdge(int u,int v)
{
e[++ENum].to = v;
e[ENum].nxt = H[u];
H[u] = ENum;
} void DFS(int x)
{
Size[x]=;//根的子树的大小(包括自己)
Dfn[x]=++cnt;//Dfn[i]:i在dfs序中的下标
for(int i=H[x];i;i=e[i].nxt)
{
int to=e[i].to;
if(Dfn[to]) continue;
DFS(to);
Size[x]+=Size[to];
}
} void PushUp(int rt)
{
Sum[rt]=Sum[rt<<]+Sum[rt<<|];
}
void PushDown(int rt)
{
if(!Sum[rt]) return;
Sum[rt<<]+=Sum[rt];
Sum[rt<<|]+=Sum[rt];
Sum[rt]=;
}
void ModifySum(int l,int r,int rt,int L,int R)
{
if(L<=l && r<=R)
{
++Sum[rt];//区间修改时 针对本题 懒标记+1
return;
}
PushDown(rt);
int m=(l+r)>>;
if(L<=m) ModifySum(l,m,rt<<,L,R);
if(m<R) ModifySum(m+,r,rt<<|,L,R);
//PushUp(rt); 不需要进行PushUp!!
}
int QuerySum(int l,int r,int rt,int p)
{
if(l==r) return Sum[rt];
PushDown(rt);
int m=(l+r)>>,res=;
if(p<=m) res+=QuerySum(l,m,rt<<,p);
else res+=QuerySum(m+,r,rt<<|,p);
return res;
} int main()
{
read(n);
for(int i=;i<n;i++)
{
int a,b;
read(a);read(b);
AddEdge(a,b);
AddEdge(b,a);
}
DFS();
// for(int i=1;i<=n;i++)
// printf("%d:dfn:%d size:%d\n",i,Dfn[i],Size[i]);
for(int i=;i<=n;i++)
{
int a;
read(a);
printf("%d\n",QuerySum(,n,,Dfn[a]));//先经过后更改
ModifySum(,n,,Dfn[a],Dfn[a]+Size[a]-);//单点查询 区间修改
}
return ;
}

洛谷P2982 [USACO10FEB]慢下来Slowing down(线段树 DFS序 区间增减 单点查询)的相关教程结束。

相关推荐:

计算年龄区间与评分的相关性:将文本型年龄段标准化为数值并求皮尔逊相关系数

本文介绍如何将非数值型年龄分组(如“upto25”“65andolder”)统一规范化为数值区间,再通过计算区间中位数代表该组年龄,最终与对应评分进行皮尔逊相关性分析。 本文介绍如何将非数值型年龄分组(如“upto25”“65andolder”)统一规范化为数值区间,再通过计算区间中位数代表该组年龄...

如何将年龄区间转换为数值并计算其与评分的相关系数

本文介绍如何将不规范的年龄分组(如“upto25”“65andolder”)标准化为统一的数值区间,再通过计算区间中位数生成代表年龄的连续变量,最终使用皮尔逊相关系数评估其与总体评分之间的线性关系。 本文介绍如何将不规范的年龄分组(如“upto25”“65andolder”)标准化为统一的数值区间,...

高效切割时间区间并插入指定时间点:Pandas向量化方案教程

本文介绍如何对大规模时间区间数据(70万+行)按指定时间点进行无循环、向量化切割,避免逐行迭代的性能瓶颈,将处理时间从10分钟级降至秒级。 本文介绍如何对大规模时间区间数据(70万+行)按指定时间点进行无循环、向量化切割,避免逐行迭代的性能瓶颈,将处理时间从10分钟级降至秒级。 在处理实体级时序属性...

高效切分时间区间并插入指定日期:Pandas向量化优化方案

本文介绍如何对大规模时序数据集(70万+行)中按entity_id分组的时间区间进行高效切分,将多个指定时间点(如政策生效日、系统升级日)无缝嵌入原有区间,并确保新生成的子区间完整继承原始属性值。 本文介绍如何对大规模时序数据集(70万+行)中按entity_id分组的时间区间进行高效切分,将多个指...

高效切分时间区间并插入指定时间点:Pandas向量化方案教程

本文介绍如何对大规模时间区间数据(如70万行)按指定时间点进行无循环切分,通过向量化操作替代低效的双重for循环,将处理时间从10分钟以上降至秒级。 本文介绍如何对大规模时间区间数据(如70万行)按指定时间点进行无循环切分,通过向量化操作替代低效的双重for循环,将处理时间从10分钟以上降至秒级。 ...

如何在Python中实现一致性哈希算法_解决分布式缓存中的节点增减问题

一致性哈希通过虚拟节点、有序环和二分查找实现节点增减时仅迁移局部数据,避免全量重哈希;而hash(key)%node_count在节点数变化时会导致几乎所有key映射错位,引发缓存雪崩。 直接说结论:用虚拟节点+有序环+二分查找,就能让节点增减时只迁移局部数据,避免全量重哈希。 为什么不能直接用ha...

使用 Pandas apply() 和区间映射高效分类 SIC 代码

本文介绍如何利用Pandas的apply()方法结合结构化映射规则,准确、高效地将数值型SIC行业代码(如15000、70000)批量映射为语义化行业类别(如"Construction"、"Services"),避免低效的显式循环与索引错误。 本文介绍如何利用pandas的`apply()`方法结合...