题目描述

奈特公司是一个巨大的情报公司,它有着庞大的情报网络。情报网络中共有 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. 第四次spring会议

    昨天:对TXT的字体颜色和背景进行了代码编写. 出现的问题:在网上找到如何编写代码后,自己打进去了,输出不出来.少打了一个空格在EventArgs e之间. 今天将做之事: 我设置上换肤和透明度等功能 ...

  2. 2019.02.21 bzo1038: [ZJOI2008]瞭望塔(半平面交)

    传送门 题意:给出一个nnn个点的轮廓,要求找一个高度最小的点使得它能够看见所有拐点. 思路:之间建半平面交然后取半平面交上的每个交点和每个轮廓更新答案即可. 代码: #include<bits ...

  3. QT中报错collect2:ld returned 1 exit status的可能原因。

    参考:https://blog.csdn.net/u014546553/article/details/78781547 1.编译成功的例子在后台执行,有时一闪而过,如果再次build ,则会提示上述 ...

  4. 端口转发工具lcx使用两类

    lcx是一款强大的内网端口转发工具,用于将内网主机开放的内部端口映射到外网主机(有公网IP)任意端口.它是一款命令行工具,当然也可以在有权限的webshell下执行,正因如此lcx常被认为是一款黑客入 ...

  5. Linux 线程编程2.0——线程同步-互斥锁

    当我们需要控制对共享资源的存取的时候,可以用一种简单的加锁的方法来控制.我们可以创建一个读/写程序,它们共用一个共享缓冲区,使用互斥锁来控制对缓冲区的存取. 函数 pthread_mutex_init ...

  6. less的功能和介绍

    在全新的css中,经过程序员们的开发和努力.又打造了全新的less样式表的全新界面,只需引入外部样式表即刻套用,加上了函数定义和取值.大大的降低了代码的书写量.也更加方便程序员的调用和修改!

  7. Visual Studio 2017 调试器的工作进程(msvsmon.exe)意外退出 调试将终止

    开发环境: Windows 10 in Parallels Desktop Visual Studio 15.6 场景还原: 使用 Visual Studio 15.6 (即 Visual Studi ...

  8. 背水一战 Windows 10 (74) - 控件(控件基类): UIElement - 与 CanDrag 相关的事件, 与 AllowDrop 相关的事件

    [源码下载] 背水一战 Windows 10 (74) - 控件(控件基类): UIElement - 与 CanDrag 相关的事件, 与 AllowDrop 相关的事件 作者:webabcd 介绍 ...

  9. Java代码审计入门篇

    作者:i春秋核心白帽yanzmi 原文来自:https://bbs.ichunqiu.com/thread-42149-1-1.html 本期斗哥带来Java代码审计的一些环境和工具准备. Java这 ...

  10. AndroidStudio制作“我”的界面,设置,修改密码,设置密保和找回密码

    前言 大家好,给大家带来AndroidStudio制作"我"的界面,设置,修改密码,设置密保和找回密码的概述,希望你们喜欢 学习目标 掌握修改密码功能的开发,和实现用户密码的修改: ...