Written with StackEdit.

Description

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

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

1.搜集情报:指派\(T\)号情报员搜集情报

2.传递情报:将一条情报从\(X\)号情报员传递给\(Y\)号情报员

情报员最初处于潜伏阶段,他们是相对安全的,我们认为此时所有情报员的危险值为\(0\);

一旦某个情报员开始搜集情报,他的危险值就会持续增加,每天增加1点危险值(开始搜集情报的当天危险值仍为\(0\),第\(2\)天危险值为\(1\),第\(3\)天危险值为\(2\),以此类推)。传递情报并不会使情报员的危险值增加。

为了保证传递情报的过程相对安全,每条情报都有一个风险控制值\(C\)。奈特公司认为,参与传递这条情报的所有情报员中,危险值大于\(C\)的情报员将对该条情报构成威胁。

现在,奈特公司希望知道,对于每个传递情报任务,参与传递的情报员有多少个,其中对该条情报构成威胁的情报员有多少个。

Input

第\(1\)行包含\(1\)个正整数\(n\),表示情报员个数。

笫\(2\)行包含\(n\)个非负整数,其中第\(i\)个整数\(Pi\)表示\(i\)号情报员上线的编号。特别地,若\(P_i=0\),表示\(i\)号情报员是大头目。

第\(3\)行包含\(1\)个正整数\(q\),表示奈特公司将派发\(q\)个任务(每天一个)。

随后\(q\)行,依次描述\(q\)个任务。

每行首先有\(1\)个正整数\(k\)。若\(k=1\),表示任务是传递情报,随后有3个正整数\(X_i、Y_i、C_i\),依次表示传递情报的起点、终点和风险控制值;

若\(k=2\),表示任务是搜集情报,随后有\(1\)个正整数\(T_i\),表示搜集情报的情报员编号。

Output

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

输出的行数应等于传递情报任务的个数,每行仅包含两个整数,用一个空格隔开。输出不应包含多余的空行和空格。

Sample Input

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

Sample Output

5 0

5 2

5 1

HINT

\(n< = 2×10^5,Q< = 2×105,0< P_i,C_i< = N, 1< = T_i,X_i,Y_i< = n.\)

Solution

  • 第一问求\(LCA\),第二问对树上路径查询,显然先来一个树链剖分.
  • 考虑如何解决第二问.情报员第一次被指派时,给一个当前时间\(i\)作为权值.
  • 那么每次询问,若询问的时间为\(i\),则只需要询问路径上权值\(\leq i-C-1\)的点有多少个.使用树链剖分后,即为询问区间上某个数的排名.
  • 那么只需要维护一颗树套树即可(在线比较方便),外层可以选用树状数组,因为这里询问个数是可以直接用前缀和相减的.
#include<bits/stdc++.h>
const int inf=1e9;
using namespace std;
typedef long long LoveLive;
inline int read()
{
int out=0,fh=1;
char jp=getchar();
while ((jp>'9'||jp<'0')&&jp!='-')
jp=getchar();
if (jp=='-')
{
fh=-1;
jp=getchar();
}
while (jp>='0'&&jp<='9')
{
out=out*10+jp-'0';
jp=getchar();
}
return out*fh;
}
const int MAXN=2e5+10;
int idx=0;
int x,y,z,r,p,q;
struct node{
int lson,rson,key,siz,weight;
}treap[MAXN*20];
struct FhqTreap{
int root;
FhqTreap()
{
treap[0].lson=treap[0].rson=treap[0].siz=0;
root=0;
}
#define rt treap[o]
#define ls treap[treap[o].lson]
#define rs treap[treap[o].rson]
inline int newnode(int key)
{
int o=++idx;
rt.lson=rt.rson=0;
rt.key=key;
rt.siz=1;
rt.weight=rand();
return o;
}
void pushup(int o)
{
rt.siz=ls.siz+rs.siz+1;
}
int BuildTree(int l,int r)
{
if(l>r)
return 0;
int mid=(l+r)>>1;
int o=newnode(inf);
rt.lson=BuildTree(l,mid-1);
rt.rson=BuildTree(mid+1,r);
pushup(o);
return o;
}
void split(int &x,int &y,int val,int o)
{
if(!o)
x=y=0;
else
{
if(val<rt.key)
{
y=o;
split(x,rt.lson,val,rt.lson);
}
else
{
x=o;
split(rt.rson,y,val,rt.rson);
}
pushup(o);
}
}
int merge(int X,int Y)
{
if(X==0 || Y==0)
return X+Y;
if(treap[X].weight<treap[Y].weight)
{
treap[X].rson=merge(treap[X].rson,Y);
pushup(X);
return X;
}
else
{
treap[Y].lson=merge(X,treap[Y].lson);
pushup(Y);
return Y;
}
}
void ins(int val)
{
int o=newnode(val);
root=merge(root,o);
}
int count(int lim)//<=lim
{
split(x,y,lim,root);
int res=treap[x].siz;
root=merge(x,y);
return res;
}
};
int n,m;
FhqTreap bit[MAXN];
#define lowbit(X) X&(-X)
void add(int X,int c)
{
for(;X<=n+1;X+=lowbit(X))
{
bit[X].ins(c);
}
}
int sum(int X,int lim)
{
int res=0;
for(;X;X-=lowbit(X))
res+=bit[X].count(lim);
return res;
}
int cnt=0,head[MAXN];
int nx[MAXN<<1],to[MAXN<<1];
inline void addedge(int u,int v)
{
++cnt;
to[cnt]=v;
nx[cnt]=head[u];
head[u]=cnt;
}
void insedge(int u,int v)
{
addedge(u,v);
addedge(v,u);
}
int dfn[MAXN],tid[MAXN],dfnidx=0;
int fa[MAXN],top[MAXN],dep[MAXN];
int siz[MAXN],mxson[MAXN];
void dfs1(int u,int Fa)
{
siz[u]=1;
fa[u]=Fa;
dep[u]=dep[Fa]+1;
for(int i=head[u];i;i=nx[i])
{
int v=to[i];
if(v!=Fa)
{
dfs1(v,u);
if(siz[v]>siz[mxson[u]])
mxson[u]=v;
siz[u]+=siz[v];
}
}
}
void dfs2(int u,int tp)
{
dfn[u]=++dfnidx;
tid[dfnidx]=u;
top[u]=tp;
if(mxson[u])
dfs2(mxson[u],tp);
for(int i=head[u];i;i=nx[i])
{
int v=to[i];
if(v!=fa[u] && v!=mxson[u])
dfs2(v,v);
}
}
int LCA(int u,int v)
{
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]])
swap(u,v);
u=fa[top[u]];
}
return dep[u]<dep[v]?u:v;
}
int query(int u,int v,int lim)
{
int res=0;
while(top[u]!=top[v])
{
if(dep[top[u]]<dep[top[v]])
swap(u,v);
res+=sum(dfn[u],lim)-sum(dfn[top[u]]-1,lim);
u=fa[top[u]];
}
if(dep[u]<dep[v])
swap(u,v);
res+=sum(dfn[u],lim)-sum(dfn[v]-1,lim);
return res;
}
int vis[MAXN];
int main()
{
srand(time(NULL));
n=read();
int root;
for(int i=1;i<=n;++i)
{
int p=read();
if(!p)
root=i;
else
insedge(i,p);
}
dfs1(root,0);
dfs2(root,root);
m=read();
for(int i=1;i<=m;++i)
{
int op=read();
if(op==1)
{
int u=read(),v=read(),c=read();
int lca=LCA(u,v);
int ans1=dep[u]+dep[v]-2*dep[lca]+1;
int ans2=query(u,v,i-c-1);
printf("%d %d\n",ans1,ans2);
}
else
{
int t=read();
if(!vis[t])
{
add(dfn[t],i);
vis[t]=1;
}
}
}
return 0;
}

bzoj 4448 情报传递的更多相关文章

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

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

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

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

  3. bzoj 4448 [Scoi2015]情报传递 (树链剖分+主席树)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4448 题面: Description 奈特公司是一个巨大的情报公司,它有着庞大的情报网络 ...

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

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

  5. 洛谷 4216 BZOJ 4448 [SCOI2015]情报传递

    [题解] 每个情报员的危险值val[i]应该是一个分段函数,前面一段是平行于x轴的横线,后面一段是一次函数.我们可以用fx(t)=t-b[x]表示这个一次函数.每次询问一条链上fx(t)大于c的点的个 ...

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

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

  7. dfs序+主席树 或者 树链剖分+主席树(没写) 或者 线段树套线段树 或者 线段树套splay 或者 线段树套树状数组 bzoj 4448

    4448: [Scoi2015]情报传递 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 588  Solved: 308[Submit][Status ...

  8. BZOJ 4448 主席树+树链剖分(在线)

    为什么题解都是离线的-- (抄都没法抄) 搞一棵主席树 1 操作 新树上的当前节点设成1 2 操作 查max(i-xx-1,0)那棵树上这条路径上有多少个点是1 让你找经过了多少个点 查的时候用dee ...

  9. BZOJ [Scoi2015]情报传递

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

随机推荐

  1. JS与Jquery 中的extend用法不同

    1, Jquery //jQuery 应用扩展   jQuery.extend({                  // 定义setApDiv     setApDiv:function () {  ...

  2. Windows 2008下系统网站运行环境的搭建

    1.右击[计算机]-->[管理],进入到”服务器管理器” 界面,如图所示: 2.依次展开[角色]-->[Web服务器(IIS)]-->[Internet 信息服务(IIS)管理器], ...

  3. ubuntu linux 1604 编译安装tesseract-ocr 4.0

    主要参考官方的编译,梳理一下整个流程 Linux The build instructions for Linux also apply to other UNIX like operating sy ...

  4. 【I/O】File常见用法总结

    java.io.File file可能是一个文件或者文件夹. 获取目录列表(全部/过滤) import java.io.File; import java.io.FilenameFilter; imp ...

  5. 关于MySQL的TinyInt数据类型在Delphi中作为Boolean类型的一个要注意的问题

    关于MySQL的TinyInt数据类型在Delphi中作为Boolean类型的一个要注意的问题: 在定义TinyInt类型字段时,若要作为Delphi中作为Boolean类型,则该字段的长度必须为1!

  6. C++中虚函数和纯虚函数的区别与总结

    首先:强调一个概念 定义一个函数为虚函数,不代表函数为不被实现的函数. 定义他为虚函数是为了允许用基类的指针来调用子类的这个函数. 定义一个函数为纯虚函数,才代表函数没有被实现. 定义纯虚函数是为了实 ...

  7. hdu 5777 domino 贪心

    domino Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Problem ...

  8. 简易的解决方式linker command failed with exit code 1 (use -v to see invocation)

    linker command failed with exit code 1 (use -v to see invocation) 遇到这个问题先不要慌,不用纠结是不是自己改动了什么代码导致的. 长话 ...

  9. freemarker报 java.io.FileNotFoundException:及TemplateLoader使用

    使用过freemarker的肯定其见过如下情况: java.io.FileNotFoundException: Template xxx.ftl not found. 模板找不到.可能你会认为我明明指 ...

  10. java中的几种实体类对象(PO,VO,DAO,BO,POJO)

    一.PO :(persistant object ),持久对象 可以看成是与数据库中的表相映射的java对象.使用Hibernate来生成PO是不错的选择. 二.VO :(value object) ...