题目描述

奈特公司是一个巨大的情报公司,它有着庞大的情报网络。情报网络中共有n名情报员。每名情报员口J-能有
若T名(可能没有)下线,除1名大头目外其余n-1名情报员有且仅有1名上线。奈特公司纪律森严,每
名情报员只能与自己的上、下线联系,同时,情报网络中仟意两名情报员一定能够通过情报网络传递情报。
奈特公司每天会派发以下两种任务中的一个任务:
1.搜集情报:指派T号情报员搜集情报
2.传递情报:将一条情报从X号情报员传递给Y号情报员
情报员最初处于潜伏阶段,他们是相对安全的,我们认为此时所有情报员的危险值为0;-旦某个情报员开
始搜集情报,他的危险值就会持续增加,每天增加1点危险值(开始搜集情报的当天危险值仍为0,第2天
危险值为1,第3天危险值为2,以此类推)。传递情报并不会使情报员的危险值增加。
为了保证传递情报的过程相对安全,每条情报都有一个风险控制值C。奈特公司认为,参与传递这条情
报的所有情报员中,危险值大于C的情报员将对该条情报构成威胁。现在,奈特公司希望知道,对于每
个传递情报任务,参与传递的情报员有多少个,其中对该条情报构成威胁的情报员有多少个。

输入

第1行包含1个正整数n,表示情报员个数。
笫2行包含n个非负整数,其中第i个整数Pi表示i号情报员上线的编号。特别地,若Pi=0,表示i号
情报员是大头目。
第3行包含1个正整数q,表示奈特公司将派发q个任务(每天一个)。
随后q行,依次描述q个任务。
每行首先有1个正整数k。若k=1,表示任务是传递情报,随后有3个正整数Xi、Yi、Ci,依次表示传递
情报的起点、终点和风险控制值;若k=2,表示任务是搜集情报,随后有1个正整数Ti,表示搜集情报的
情报员编号。

输出

对于每个传递情报任务输出一行,应包含两个整数,分别是参与传递情报的情报员个数和对该条情报构成威胁的情报员个数。
输出的行数应等于传递情报任务的个数,每行仅包含两个整数,用一个空格隔开。输出不应包含多余的空行和空格。

样例输入

7
0 1 1 2 2 3 3
6
1 4 7 0
2 1
2 4
2 7
1 4 7 1
1 4 7 3

样例输出

5 0
5 2
5 1

提示

对于3个传递情报任务,都是经过5名情报员,分别是4号、2号、1号、3号和7号。其中,对于第1个
任务,所有情报员(危险值为0)都不对情报构成威胁;对于第2个任务,有2名情报员对情报构成威胁,
分别是1号情报员(危险值为3)和4号情报员(危险值为2),7号情报员(危险值为1)并不构成威胁;
对于第3个任务,只有1名情报员对情报构成威胁。
n< = 2×10^5,Q< = 2×105,0< Pi,C!< = N, 1< = Ti,Xi,Yi< = n
 
  
  树上主席树,先把所有操作读进来,记录每个点开始调查情报时间,再dfs一遍整棵树,在每个点建一棵主席树,每个点的主席树状态由父节点转移过来。
对于第i次操作询问x,y,c,就是查询路径在主席树上的信息中开始调查情报的时间在i-c之前有几个点。
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
struct node
{
int opt;
int x,y;
int z;
}a[200010];
int n,m;
int tot;
int cnt;
int rot;
int v[200010];
int d[200010];
int to[200010];
int ls[6000010];
int rs[6000010];
int sum[6000010];
int root[1000010];
int head[200010];
int next[200010];
int f[200010][20];
void add(int x,int y)
{
tot++;
next[tot]=head[x];
head[x]=tot;
to[tot]=y;
}
void dfs(int x,int fa)
{
d[x]=d[fa]+1;
for(int i=1;i<=19;i++)
{
f[x][i]=f[f[x][i-1]][i-1];
}
for(int i=head[x];i;i=next[i])
{
dfs(to[i],x);
}
}
int lca(int x,int y)
{
if(d[x]<d[y])
{
swap(x,y);
}
int dep=d[x]-d[y];
for(int i=0;i<=19;i++)
{
if((dep&(1<<i))!=0)
{
x=f[x][i];
}
}
if(x==y)
{
return x;
}
for(int i=19;i>=0;i--)
{
if(f[x][i]!=f[y][i])
{
x=f[x][i];
y=f[y][i];
}
}
return f[x][0];
}
int updata(int pre,int l,int r,int k)
{
int rt=++cnt;
if(l==r)
{
sum[rt]++;
return rt;
}
ls[rt]=ls[pre];
rs[rt]=rs[pre];
sum[rt]=sum[pre]+1;
int mid=(l+r)>>1;
if(k<=mid)
{
ls[rt]=updata(ls[pre],l,mid,k);
}
else
{
rs[rt]=updata(rs[pre],mid+1,r,k);
}
return rt;
}
void build(int x,int fa)
{
root[x]=root[fa];
if(v[x]!=0)
{
root[x]=updata(root[fa],1,m,v[x]);
}
for(int i=head[x];i;i=next[i])
{
build(to[i],x);
}
}
int query(int x,int y,int fa,int anc,int l,int r,int k)
{
if(l==r)
{
return sum[x]+sum[y]-sum[fa]-sum[anc];
}
int res=sum[ls[x]]+sum[ls[y]]-sum[ls[fa]]-sum[ls[anc]];
int mid=(l+r)>>1;
if(k<=mid)
{
return query(ls[x],ls[y],ls[fa],ls[anc],l,mid,k);
}
else
{
return res+query(rs[x],rs[y],rs[fa],rs[anc],mid+1,r,k);
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&f[i][0]);
add(f[i][0],i);
}
for(int i=1;i<=n;i++)
{
if(f[i][0]==0)
{
rot=i;
dfs(i,0);
break;
}
}
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
scanf("%d",&a[i].opt);
if(a[i].opt==1)
{
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
}
else
{
scanf("%d",&a[i].z);
v[a[i].z]=i;
}
}
build(rot,0);
for(int i=1;i<=m;i++)
{
if(a[i].opt==1)
{
int anc=lca(a[i].x,a[i].y);
printf("%d ",d[a[i].x]+d[a[i].y]-d[anc]-d[f[anc][0]]);
if(i-a[i].z-1<=0)
{
printf("0\n");
continue;
}
printf("%d\n",query(root[a[i].x],root[a[i].y],root[anc],root[f[anc][0]],1,m,i-a[i].z-1));
}
}
}

BZOJ4448[Scoi2015]情报传递——主席树+LCA的更多相关文章

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

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

  2. bzoj4448 [Scoi2015]情报传递 主席树+树上差分

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4448 题解 练习一下主席树的基础练习题找回感觉. 对于每一次询问,第一问显然随便做. 第二问的 ...

  3. 【bzoj4448】[Scoi2015]情报传递 主席树

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

  4. bzoj 4448 [Scoi2015]情报传递 主席树

    比较套路的题目. 可以发现难点在于某个点的权值动态修改 且我们要维护树上一条路径上的点权>x的个数. 每个点都在动态修改 这意味着我们的只能暴力的去查每个点. 考虑将所有可以动态修改的点变成静态 ...

  5. 4448: [Scoi2015]情报传递|主席树|离线操作

    能够把全部的操作离线,然后树链剖分将全部人搜集情报的时间增加到主席树中,查询的时候能够直接查询搜集情报时间≤i−C[i]−1的人的个数 时间复杂度n∗log22n,空间复杂度n∗log2n #incl ...

  6. Count on a tree SPOJ 10628 主席树+LCA(树链剖分实现)(两种存图方式)

    Count on a tree SPOJ 10628 主席树+LCA(树链剖分实现)(两种存图方式) 题外话,这是我第40篇随笔,纪念一下.<( ̄︶ ̄)↗[GO!] 题意 是说有棵树,每个节点上 ...

  7. BZOJ4448 SCOI2015情报传递(离线+树链剖分+树状数组)

    即滋磁单点修改,询问路径上小于某数的值有多少个.暴力树剖套个主席树(或者直接树上主席树,似乎就1个log了?感觉不一定比两个log快)即可,然而不太优美. 开始觉得可以cdq,然而就变成log^3了. ...

  8. 洛谷P4216 [SCOI2015]情报传递(树剖+主席树)

    传送门 我们可以进行离线处理,把每一个情报员的权值设为它开始收集情报的时间 那么设询问的时间为$t$,就是问路径上有多少个情报员的权值小于等于$t-c-1$ 这个只要用主席树上树就可以解决了,顺便用树 ...

  9. bzoj4448 SCOI2015 情报传递 message

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

随机推荐

  1. 【Codeforces 1105E】Helping Hiasat

    Codeforces 1105 E 题意:给你m个事件,每个事件可能是以下两种之一: \(1\),代表此时可以更改用户名 \(2\) \(s\),代表\(s\)来查看是否用户名与其名字相符 一共有\( ...

  2. Linux命令——df/du/time

    一.df(disk free) df命令可以用来检查 linux服务器的文件系统的磁盘空间占用情况,可以知道硬盘被占用了多少空间,目前还剩下多少空间等信息. 1)命令格式 df [参数] 文件名 2) ...

  3. SkylineGlobe 如何使用二次开发接口创建粒子效果

    SkylineGlobe在6.6版本,ICreator66接口新增加了CreateEffect方法,用来创建粒子效果对象: 以及ITerrainEffect66对象接口,可以灵活设置粒子效果对象的相关 ...

  4. 使用Webuploader大文件分片传输

    背景:50G大文件的HTTP上传至服务器. 好了,根据这个命题,可以开始研究我们怎么做才能把这么大的文件上传成功. 分片上传是肯定的,断点续传也是要有的,进度可视化那就更好了,基于这些,我选择了Web ...

  5. TCP/IP协议--TCP协议概括和TCP连接的建立和终止

    TCP提供一种面向连接的.可靠的字节流服务.面向连接指,发送和接收方在交换数据前必须建立一个TCP连接.顺便说下,一个TCP连接只有两方,因此广播和多播是不能应用于TCP的.字节流指,两个应用程序通过 ...

  6. Java使用数字证书加密通信(加解密/加签验签)

    本文中使用的Base64Utils.java可参考:http://www.cnblogs.com/shindo/p/6346618.html 证书制作方法可参考:http://www.cnblogs. ...

  7. 【IDEA】Intellij IDEA创建的Web项目配置Tomcat并启动Maven项目

    转载请注明出处:http://blog.csdn.net/qq_26525215本文源自[大学之旅_谙忆的博客] 本篇博客讲解IDEA如何配置Tomcat. 大部分是直接上图哦. 点击如图所示的地方, ...

  8. hdu 3038 给区间和,算出多少是错的

    参考博客 How Many Answers Are Wrong Problem Description TT and FF are ... friends. Uh... very very good ...

  9. C. A Mist of Florescence

    链接 [http://codeforces.com/contest/989/problem/C] 题意 给定A B C D四个字符个数,让你构造一个矩阵使得他们的个数恰好那么多,联通块算一块 分析 构 ...

  10. 《Linux内核设计与实现》第3章读书整理

    第三章.进程管理 3.1进程 1.进程就是处于执行期的程序,但进程并不仅仅局限于一段可执行程序代码 2.执行线程: 简称线程,是在进程中活动的对象.每个线程都拥有一个独立的程序计数器.进程栈和一组进程 ...