【[SCOI2015]情报传递】
非常无脑的板子题,就当是练一下板子
我们可以先将所有的操作离线下来,之后那些搜集过情报的点就有了点权,对于查询操作,就是查询一下这条路径上有几个点点权满足\(st<=now-C+1\)
#include<iostream>
#include<cstdio>
#include<cstring>
#define re register
#define maxn 200005
int n,cnt,tot,m,num;
int l[maxn*29],r[maxn*29],d[maxn*29];
int rt[maxn],a[maxn];
int cur;
int X[maxn],Y[maxn],C[maxn],Day[maxn];
int build(int x,int y)
{
int root=++cnt;
if(x==y) return root;
int mid=x+y>>1;
l[root]=build(x,mid),r[root]=build(mid+1,y);
return root;
}
int change(int pre,int x,int y,int pos)
{
int root=++cnt;
d[root]=d[pre]+1;
if(x==y) return root;
l[root]=l[pre],r[root]=r[pre];
int mid=x+y>>1;
if(pos<=mid) l[root]=change(l[pre],x,mid,pos);
else r[root]=change(r[pre],mid+1,y,pos);
return root;
}
struct E
{
int v,nxt;
}e[maxn<<1];
int head[maxn],sum[maxn],son[maxn],top[maxn],fa[maxn],deep[maxn];
inline void add_edge(int x,int y)
{
e[++num].v=y;
e[num].nxt=head[x];
head[x]=num;
}
void dfs1(int x)
{
rt[x]=change(rt[fa[x]],1,n+1,a[x]);
sum[x]=1;
int maxx=-1;
for(re int i=head[x];i;i=e[i].nxt)
if(!deep[e[i].v])
{
deep[e[i].v]=deep[x]+1;
fa[e[i].v]=x;
dfs1(e[i].v);
sum[x]+=sum[e[i].v];
if(sum[e[i].v]>maxx) maxx=sum[e[i].v],son[x]=e[i].v;
}
}
void dfs2(int x,int topf)
{
top[x]=topf;
if(!son[x]) return;
dfs2(son[x],topf);
for(re int i=head[x];i;i=e[i].nxt)
if(deep[e[i].v]>deep[x]&&e[i].v!=son[x]) dfs2(e[i].v,e[i].v);
}
inline int LCA(int x,int y)
{
while(top[x]!=top[y])
{
if(deep[top[x]]<deep[top[y]]) std::swap(x,y);
x=fa[top[x]];
}
if(deep[x]<deep[y]) return x;
return y;
}
inline int read()
{
char c=getchar();
int x=0;
while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9')
x=(x<<3)+(x<<1)+c-48,c=getchar();
return x;
}
int query(int p1,int p2,int p3,int p4,int x,int y,int ll,int rr)
{
if(ll<=x&&rr>=y) return d[p1]+d[p2]-d[p3]-d[p4];
int mid=x+y>>1;
if(rr<=mid) return query(l[p1],l[p2],l[p3],l[p4],x,mid,ll,rr);
if(ll>mid) return query(r[p1],r[p2],r[p3],r[p4],mid+1,y,ll,rr);
return query(l[p1],l[p2],l[p3],l[p4],x,mid,ll,rr)+query(r[p1],r[p2],r[p3],r[p4],mid+1,y,ll,rr);
}
int main()
{
n=read();
int RT=0,x;
for(re int i=1;i<=n;i++)
{
x=read();
if(!x) RT=i;
else add_edge(x,i);
}
rt[0]=build(1,n+1);
m=read();
int opt;
for(re int i=1;i<=m;i++)
{
opt=read();
if(opt==1) X[++cur]=read(),Y[cur]=read(),C[cur]=read(),Day[cur]=i;
else a[read()]=i;
}
for(re int i=0;i<=n+1;i++)
if(!a[i]) a[i]=n+1;
rt[0]=change(rt[0],1,n+1,n+1);
deep[RT]=1,dfs1(RT),dfs2(RT,RT);
for(re int i=1;i<=cur;i++)
{
int lca=LCA(X[i],Y[i]);
printf("%d ",deep[X[i]]+deep[Y[i]]-2*deep[lca]+1);
if(Day[i]-C[i]-1<1) puts("0");
else printf("%d\n",query(rt[X[i]],rt[Y[i]],rt[lca],rt[fa[lca]],1,n+1,1,Day[i]-C[i]-1));
}
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号情报员传递 ...
- [SCOI2015] 情报传递
题目描述 奈特公司是一个巨大的情报公司,它有着庞大的情报网络.情报网络中共有 n 名情报员.每名情报员可能有若干名 (可能没有) 下线,除 1 名大头目外其余 n−1 名情报员有且仅有 1 名上线.奈 ...
随机推荐
- for循环注意案例
1.在for循环中,三个表达式都可以省略,但是分号必须编写,但会出现死循环(无限循环) 2.在for循环中,省略表达式1,则出现编译错误,解决办法:在表达式1编写在for循环上面 3.在for循环中, ...
- Android应用程序组件之间的通信Intent和IntentFilter
Android应用程序的基本组件,这些基本组建除了Content Provider之外,几乎全部都是依靠Intent对象来激活和通信的. 下面介绍Intent类,并通过例子来说明Intent一般用法 ...
- STL:set用法总结
一:介绍 set是STL的关联式容器,以红黑树(Red-Black Tree)作为底层数据结构.自动去重,保证每个元素唯一,并对数据进行排序. 命名空间为std,所属头文件为<set> 二 ...
- Coursera 机器学习 第8章(上) Unsupervised Learning 学习笔记
8 Unsupervised Learning8.1 Clustering8.1.1 Unsupervised Learning: Introduction集群(聚类)的概念.什么是无监督学习:对于无 ...
- bzoj 5084: hashit
Description 你有一个字符串S,一开始为空串,要求支持两种操作 在S后面加入字母C 删除S最后一个字母 问每次操作后S有多少个两两不同的连续子串 Solution 先忽略删除操作,建出最终的 ...
- linux修改文件权限命令(chmod)
chmod命令是用于改变文件或目录的访问权限.用户用它控制文件或目录的访问权限. 该命令有两种用法.一种是包含字母和操作符表达式的文字设定法:另一种是包含数字的数字设定法. 1.文字设定法 chmod ...
- sql使用自连接去重复查询
查询公司与公司最新刷新的一条信息 select t1.userid,t1.id,t1.title,t1.RegType,t1.Salary,t1.SubjectID,t1.RefreshTime,t2 ...
- 06.FileStream类的学习
//FileStream类是用来操作字节的,也就是可以操作所有文件. 因为所有的文件都是以字节形式来存储的. //StreamReader类和StreamWriter类是用来操作字符的. FileSt ...
- libtar 和 libz 的使用
libtar 和 libz 的使用 用c代码生成 tar.gz 文件 实现的功能和 tar -zcf 命令一样 大概流程为 1.先用libtar相关函数对某个目录生成tar文件 2.然后对tar文件 ...
- js之strict模式
JavaScript在设计之初,为了方便初学者学习,并不强制要求用var申明变量.这个设计错误带来了严重的后果:如果一个变量没有通过var申明就被使用,那么该变量就自动被申明为全局变量: i = 10 ...