题目描述

奈特公司是一个巨大的情报公司,它有着庞大的情报网络。情报网络中共有 n 名情报员。每名情报员可能有若干名 (可能没有) 下线,除 1 名大头目外其余 n−1 名情报员有且仅有 1 名上线。奈特公司纪律森严,每名情报员只能与自己的上、下线联系,同时,情报网络中任意两名情报员一定能够通过情报网络传递情报。

奈特公司每天会派发以下两种任务中的一个任务:

  1. 搜集情报:指派 T 号情报员搜集情报;
  2. 传递情报:将一条情报从 X 号情报员传递给 Y号情报员。

情报员最初处于潜伏阶段,他们是相对安全的,我们认为此时所有情报员的危险值为 0 ;一旦某个情报员开始搜集情报,他的危险值就会持续增加,每天增加 1点危险值 (开始搜集情报的当天危险值仍为 0 ,第 2 天危险值为 1 ,第 3 天危险值为 2 ,以此类推)。传递情报并不会使情报员的危险值增加。

为了保证传递情报的过程相对安全,每条情报都有一个风险控制值 C 。奈特公司认为,参与传递这条情报的所有情报员中,危险值大于 C 的情报员将对该条情报构成威胁。现在,奈特公司希望知道,对于每个传递情报任务,参与传递的情报员有多少个,其中对该条情报构成威胁的情报员有多少个。

Input

第一行包含一个正整数 n ,表示情报员个数。 笫二行包含 n 个非负整数,其中第 i 个整数 Pi 表示 i 号情报员上线的编号。特别地,若 Pi=0 ,表示 i 号情报员是大头目。 第三行包含一个正整数 q ,表示奈特公司将派发 q 个任务 (每天一个)。

随后 q 行,依次描述 q 个任务。每行首先有一个正整数 kk 。

  • 若 k=1 ,表示任务是传递情报,随后有三个正整数 Xi 、Yi 、Ci ,依次表示传递情报的起点、终点和风险控制值。
  • 若 k=2 ,表示任务是搜集情报,随后有 1 个正整数 Ti ,表示搜集情报的情报员编号。

Output

对于每个传递情报任务输出一行,包含两个整数,分别是参与传递情报的情报员个数和对该条情报构成威胁的情报员个数。

Hint

\(n\leqslant 2\times 10^5,Q\leqslant 2\times 10^5,0<P_i,C_i\leqslant N,1\leqslant T_i,X_i,Y_i\leqslant n\)

Solution

将收集情报看作染色操作,那么对于编号为 \(idx\) 的询问,显然要求的是在 \(idx-c-1\) 或更早这一条链上有多少点被染过色。

容易想到离线处理,按照 \(idx-c-1\) 从小到大排序,并实时树上染色。

对于求两点距离,显然可以用两点深度之和再减去 \(lca\) 的深度的二倍,求 \(lca\) 可以在做第二问时顺便求出,所以我们返回一个 \(pair\) 类型即可。

Code

#include<cstdio>
#include<cctype>
#include<algorithm>
#define N 200005
#define blank putchar(' ')
#define nxtline putchar('\n')
#define max(A,B) ((A)>(B)?(A):(B))
#define min(A,B) ((A)<(B)?(A):(B))
#define swap(A,B) ((A)^=(B)^=(A)^=(B)) int ques[N][5],q;
int n,m,cnt,pos,tot;
int sze[N],son[N],fa[N];
int sum[N<<2],ans[N],d[N];
int head[N],dfn[N],top[N]; struct Node{
int x,y,z;
int idx,ans1,ans2;
}node[N]; struct Edge{
int to,nxt;
}edge[N]; void add(int x,int y){
edge[++cnt].to=y;
edge[cnt].nxt=head[x];
head[x]=cnt;
} bool cmp1(Node a,Node b){
return a.idx-a.z<b.idx-b.z;
} bool cmp2(Node a,Node b){
return a.idx<b.idx;
} int getint(){
int x=0;char ch=getchar();
while(!isdigit(ch)) ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return x;
} void write(int x){
if(x>9) write(x/10);
putchar(x%10+'0');
} void first_dfs(int now){
sze[now]=1;
for(int i=head[now];i;i=edge[i].nxt){
int to=edge[i].to;
d[to]=d[now]+1;
fa[to]=now;
first_dfs(to);
sze[now]+=sze[to];
if(sze[to]>sze[son[now]])
son[now]=to;
}
} void second_dfs(int now,int low){
top[now]=low;
dfn[now]=++tot;
if(son[now])
second_dfs(son[now],low);
for(int i=head[now];i;i=edge[i].nxt){
int to=edge[i].to;
if(to==son[now])
continue;
second_dfs(to,to);
}
} void pushup(int cur){
sum[cur]=sum[cur<<1]+sum[cur<<1|1];
} void modify(int cur,int l,int r,int ql,int qr){
if(l==r){
sum[cur]=1;
return;
}
int mid=l+r>>1;
if(ql<=mid)
modify(cur<<1,l,mid,ql,qr);
else
modify(cur<<1|1,mid+1,r,ql,qr);
pushup(cur);
} int query(int cur,int l,int r,int ql,int qr){
if(ql<=l and r<=qr)
return sum[cur];
int mid=l+r>>1,ans=0;
if(ql<=mid)
ans+=query(cur<<1,l,mid,ql,qr);
if(mid<qr)
ans+=query(cur<<1|1,mid+1,r,ql,qr);
return ans;
} std::pair<int,int> ask(int x,int y){
int ans=0;
while(top[x]!=top[y]){
if(d[top[x]]<d[top[y]])
swap(x,y);
ans+=query(1,1,n,dfn[top[x]],dfn[x]);
x=fa[top[x]];
}
if(d[x]<d[y])
swap(x,y);
ans+=query(1,1,n,dfn[y],dfn[x]);
return std::make_pair(y,ans);
} signed main(){
n=getint();int root;
for(int i=1;i<=n;i++){
int p=0;
if((p=getint())==0)
root=i;
else
add(p,i);
}
first_dfs(root);second_dfs(root,root);
m=getint();
for(int i=1;i<=m;i++){
if(getint()==1){
node[++pos].x=getint();
node[pos].y=getint();
node[pos].z=getint();
node[pos].idx=i;
} else{
ques[++q][1]=getint();
ques[q][2]=i;
}
}
std::sort(node+1,node+1+pos,cmp1);
int now=0;
for(int i=1;i<=pos;i++){
while(now<q and node[i].idx-node[i].z>ques[now+1][2]){
now++;
modify(1,1,n,dfn[ques[now][1]],dfn[ques[now][1]]);
}
std::pair<int,int> p=ask(node[i].x,node[i].y);
node[i].ans1=d[node[i].x]+d[node[i].y]+1-2*d[p.first];
node[i].ans2=p.second;
}
std::sort(node+1,node+1+pos,cmp2);
for(int i=1;i<=pos;i++){
write(node[i].ans1);blank;
write(node[i].ans2);nxtline;
}
return 0;
}

[SCOI2015] 情报传递的更多相关文章

  1. BZOJ_4448_[Scoi2015]情报传递_主席树

    BZOJ_4448_[Scoi2015]情报传递_主席树 Description 奈特公司是一个巨大的情报公司,它有着庞大的情报网络.情报网络中共有n名情报员.每名情报员口J-能有 若T名(可能没有) ...

  2. BZOJ 4448: [Scoi2015]情报传递 树链剖分 主席树

    4448: [Scoi2015]情报传递 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4448 Description 奈特公司是一个巨 ...

  3. 【BZOJ4448】[Scoi2015]情报传递 主席树+LCA

    [BZOJ4448][Scoi2015]情报传递 Description 奈特公司是一个巨大的情报公司,它有着庞大的情报网络.情报网络中共有n名情报员.每名情报员能有若干名(可能没有)下线,除1名大头 ...

  4. [SCOI2015]情报传递[树剖+主席树]

    [SCOI2015]情报传递 题意大概就是 使得在 \(i\) 时刻加入一个情报员帮您传情报 然后询问 \(x,y,c\) 指 \(x\)到\(y\)多少个人有风险-(大于c)的都有风险-每天风险值+ ...

  5. bzoj4448 [Scoi2015]情报传递

    第一问不解释,对于第二问的处理,可以使用cdq分治,假设分治的询问区间是[L,R],那么我们对于标号在[L,mid]的修改操作赋予一个权值,因为在当前[L,R]中[L,mid]的修改操作只会对[mid ...

  6. bzoj 4448 [Scoi2015]情报传递(主席树,LCA)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4448 [题意] 给定一颗树,询问一条路径上权值小于t-c的点数. [思路] 将一个2查 ...

  7. bzoj4448 SCOI2015 情报传递 message

    传送门bzoj4448 题解 离线之后构建树上主席树,每个点的线段树维护到根路径的信息,不用链剖(我的链剖只是拿来求\(\mathrm{lca}\)的),时空复杂度\(O(n\log{n})\). c ...

  8. bzoj 4448: [Scoi2015]情报传递

    Description 奈特公司是一个巨大的情报公司,它有着庞大的情报网络.情报网络中共有n名情报员.每名情报员口J-能有 若T名(可能没有)下线,除1名大头日外其余n-1名情报员有且仅有1名上线.奈 ...

  9. 2019.03.26 bzoj4448: [Scoi2015]情报传递(归并排序+树链剖分)

    传送门 题意简述: 给一棵nnn个点的树,树上每个点表示一个情报员,一共有mmm天,每天会派发以下两种任务中的一个任务: 1.搜集情报:指派T号情报员搜集情报 2.传递情报:将一条情报从X号情报员传递 ...

随机推荐

  1. vector容器用法详解

    vector类称作向量类,它实现了动态数组,用于元素数量变化的对象数组.像数组一样,vector类也用从0开始的下标表示元素的位置:但和数组不同的是,当vector对象创建后,数组的元素个数会随着ve ...

  2. js--随机产生100个从0 ~ 1000之间不重复的整数(me)

    <style>       div{text-indent:40px;} </style> <script> window.onload=function(){ v ...

  3. # 2019-2020.3 《java程序设计》第一周学习总结

    2019-2020-3 <Java 程序设计>第一周学习总结 在本周的学习中,学习到了好多也收获了好多,从最基础的安装虚拟机开始,根据老师的博客中的教程一步一步的进行,在这过程中也遇到了好 ...

  4. 如何监控redis的cpu使用率

    redis默认是单线程运行的,为了充分利用机器的cpu,正常情况下一台服务器上会装多个实例.如果通过top命令监控机器的cpu的话,监控值很笼统,不能精确到单redis实例的cpu使用率监控.而且ce ...

  5. HDU 2639 01背包(分解)

    http://acm.hdu.edu.cn/showproblem.php?pid=2639 01背包第k优解,把每次的max分步列出来即可 #include<stdio.h> #incl ...

  6. PowerBuilder常用字符串函数

    http://blog.sina.com.cn/s/blog_5995b53d0100a694.html Fill()功能建立一个由指定字符串填充的指定长度的字符串.语法Fill ( chars, n ...

  7. Navie level questions

    1. Binary Tree Maximum Node Find the maximum node in a binary tree,return the node. public class Max ...

  8. MyBatis 源码分析 - 配置文件解析过程

    * 本文速览 由于本篇文章篇幅比较大,所以这里拿出一节对本文进行快速概括.本篇文章对 MyBatis 配置文件中常用配置的解析过程进行了较为详细的介绍和分析,包括但不限于settings,typeAl ...

  9. AJPFX简述:MetaTrader 4移动交易平台

    (AJPFX)移动交易平台可以让客户随时通过客户手中的移动设备例如智能手机.PDA等管理自己帐户和进行交易.移动交易平台提供了完整的交易帐户管理分析选项,当客户无法使用台式计算机的时候,移动交易平台为 ...

  10. Django _VIEW视图_源码分析

    Django _VIEW视图: 1. 点击as_view方法. 第二步: as_view () 为VIEW 类里定义的,到时候我们定义业务逻辑的类就继承这个VIEW类. view方法内返回的是disp ...