[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号情报员传递 ...
随机推荐
- Django Model模型的实战操作笔记
Model模型的实战操作笔记 1. 创建数据库和表 进入MySQL数据库创建数据库:mytest 进入数据库创建数据表:mytest_users CREATE TABLE `mytest_users` ...
- 【转】《深入理解C# 3.x的新特性》博文系列汇总
[转]<深入理解C# 3.x的新特性>博文系列汇总 较之C# 2.0, C# 3.x引入了一系列新的特性,为我们编程带来很大的便利,通过有效地利用这些新特性,我们可以编写出更加简洁.优雅的 ...
- qhfl-7 结算中心
结算中心,即从购物车前往支付前的确认页面,这里要开始选择优惠券了 """ 前端传过来数据 course_list 课程列表 redis 中将要存放的结算数据 { sett ...
- Cannot set property 'onclick' of null报错
经常几个页面使用公共js文件, 原来遇到也没留意, 原来是本页面执行的时候, 其他页面也在执行并赋予id于onclick. 因为页面是正常情况下是不存在null和undefined if(null){ ...
- visual2017专业版MFC编程环境搭建及第一个MFC程序的创建
1.MFC介绍及环境搭建 MFC全程为Microsoft Foundation class Library,即微软的基本类库,MFC实际上是一个庞大的文件库,它由指向文件和源文件组成. 首先,打开vi ...
- django自定义user认证系统
第一种,彻底推翻django的user认证系统,重新定义我们想要的字段 from django.contrib.auth.models import AbstractBaseUser,Permissi ...
- Laravel在进行表单验证时,错误信息未返回
马上要毕业了,找了现在的这家公司,压力不大,自己也比较喜欢,唯一的遗憾就是手机号莫得换了(找不到换的借口). 进入正题: 之前自己的博客(http://lxiaoke.cn)是用ThinkPHP开发的 ...
- Linux pwn入门教程(6)——格式化字符串漏洞
作者:Tangerine@SAINTSEC 0x00 printf函数中的漏洞 printf函数族是一个在C编程中比较常用的函数族.通常来说,我们会使用printf([格式化字符串],参数)的形式来进 ...
- Mybatis框架一:搭建测试
Mybatis框架不再介绍: 在JDBC中存在一些问题: 1.频繁连接和释放资源浪费内存 2.编码完成后不便于维护 于是产生了简化数据库操作的框架:Hibernate.Mybatis等等,这里介绍My ...
- spring boot、cloud v2.1.0.RELEASE 使用及技术整理
2018年10月30日 springboot v2.1.0.RELEASE 发布: https://github.com/spring-projects/spring-boot/releases/ta ...