[SCOI2015] 情报传递
题目描述
奈特公司是一个巨大的情报公司,它有着庞大的情报网络。情报网络中共有 n 名情报员。每名情报员可能有若干名 (可能没有) 下线,除 1 名大头目外其余 n−1 名情报员有且仅有 1 名上线。奈特公司纪律森严,每名情报员只能与自己的上、下线联系,同时,情报网络中任意两名情报员一定能够通过情报网络传递情报。
奈特公司每天会派发以下两种任务中的一个任务:
- 搜集情报:指派 T 号情报员搜集情报;
- 传递情报:将一条情报从 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] 情报传递的更多相关文章
- BZOJ_4448_[Scoi2015]情报传递_主席树
BZOJ_4448_[Scoi2015]情报传递_主席树 Description 奈特公司是一个巨大的情报公司,它有着庞大的情报网络.情报网络中共有n名情报员.每名情报员口J-能有 若T名(可能没有) ...
- BZOJ 4448: [Scoi2015]情报传递 树链剖分 主席树
4448: [Scoi2015]情报传递 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4448 Description 奈特公司是一个巨 ...
- 【BZOJ4448】[Scoi2015]情报传递 主席树+LCA
[BZOJ4448][Scoi2015]情报传递 Description 奈特公司是一个巨大的情报公司,它有着庞大的情报网络.情报网络中共有n名情报员.每名情报员能有若干名(可能没有)下线,除1名大头 ...
- [SCOI2015]情报传递[树剖+主席树]
[SCOI2015]情报传递 题意大概就是 使得在 \(i\) 时刻加入一个情报员帮您传情报 然后询问 \(x,y,c\) 指 \(x\)到\(y\)多少个人有风险-(大于c)的都有风险-每天风险值+ ...
- bzoj4448 [Scoi2015]情报传递
第一问不解释,对于第二问的处理,可以使用cdq分治,假设分治的询问区间是[L,R],那么我们对于标号在[L,mid]的修改操作赋予一个权值,因为在当前[L,R]中[L,mid]的修改操作只会对[mid ...
- bzoj 4448 [Scoi2015]情报传递(主席树,LCA)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4448 [题意] 给定一颗树,询问一条路径上权值小于t-c的点数. [思路] 将一个2查 ...
- bzoj4448 SCOI2015 情报传递 message
传送门bzoj4448 题解 离线之后构建树上主席树,每个点的线段树维护到根路径的信息,不用链剖(我的链剖只是拿来求\(\mathrm{lca}\)的),时空复杂度\(O(n\log{n})\). c ...
- bzoj 4448: [Scoi2015]情报传递
Description 奈特公司是一个巨大的情报公司,它有着庞大的情报网络.情报网络中共有n名情报员.每名情报员口J-能有 若T名(可能没有)下线,除1名大头日外其余n-1名情报员有且仅有1名上线.奈 ...
- 2019.03.26 bzoj4448: [Scoi2015]情报传递(归并排序+树链剖分)
传送门 题意简述: 给一棵nnn个点的树,树上每个点表示一个情报员,一共有mmm天,每天会派发以下两种任务中的一个任务: 1.搜集情报:指派T号情报员搜集情报 2.传递情报:将一条情报从X号情报员传递 ...
随机推荐
- 【转】背后的故事之 - 快乐的Lambda表达式(一)
快乐的Lambda表达式(二) 自从Lambda随.NET Framework3.5出现在.NET开发者眼前以来,它已经给我们带来了太多的欣喜.它优雅,对开发者更友好,能提高开发效率,天啊!它还有可能 ...
- linux的system () 函数详解
linux的system () 函数详解 system(执行shell 命令)相关函数 fork,execve,waitpid,popen表头文件 #i nclud ...
- xbee/xbeeRPOS1、xbee/xbeePROS2C802.15.4/Digimesh功能方法
Digi XBee 802.15.4的第一个版本也称为S1,是基于Freescale的无线收发器片子设计的.最新的802.15.4模块(内部称号S1B)采用和Digi ZigBee模块相同SOC芯片设 ...
- Spring-Data-JPA @Query注解 Sort排序
当我们使用方法名称很难,达到预期的查询结果,就可以使用@Query进行查询,@Query是一种添加自定义查询的便利方式 (方法名称查询见http://blog.csdn.net/niugang0920 ...
- AdminLTE用django部署
前言 最近从网上看到AdminLTE这个web前端的主题挺好的,我平时用python就是写一些后台,准备以后就用这个框架了,这里就是把这个用django初始化一下这个项目. 基础环境介绍 Python ...
- 参数签名ascii码排序的坑
参数签名中通常是按键值对中键名称的ASCII按从小到大的顺序排序后进行hash为签名字符串.不要直接使用 SortedDictionary<string, string> 有坑的,他是按数 ...
- ASP.NET MVC下使用AngularJs语言(三):ng-options
今天使用angularjs的ng-options实现一个DropDownList下拉列表. 准备ASP.NET MVC的model: public class MobilePhone { public ...
- 背水一战 Windows 10 (72) - 控件(控件基类): UIElement - UIElement 的位置, UIElement 的布局, UIElement 的其他特性
[源码下载] 背水一战 Windows 10 (72) - 控件(控件基类): UIElement - UIElement 的位置, UIElement 的布局, UIElement 的其他特性 作者 ...
- MongoDB 数据库
数据库: 关系型数据库 mysql 收费 速度快 字段类型 非关系型数据库 MongoDB 不收费 速度慢一些 存储数据都是字符串 ...
- JavaScript获取键盘事件
JavaScript中: onkeydown 事件会在用户按下一个键盘按键时发生. onkeypress 事件会在键盘按键被按下并释放一个键时发生. onkeyup 事件会在键盘按键被松开时发生. 支 ...