【bzoj4448】[Scoi2015]情报传递 主席树
题目描述
输入
输出
样例输入
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
题目大意
给出一棵树,有两种操作:1.标记一个点;2.询问两点间路径长度及路径上上有多少个点在 当前时间减去ci 之前被标记过
题解
主席树
看懂了题就好做多了。
考虑到修改操作比较麻烦,由于c>0,表明后面对前面没有影响,可以调换顺序。
我们可以离线处理,先将所有点标记上(即赋权值为标记时间),然后离线查找即可。
之后就是套路,点x在fa[x]之上建立主席树,查询x、y时相当于1->x + 1->y - 1->lca(x,y) - 1->fa[lca(x,y)]。
注意一下 当前时间-ci<=0 时的特判
#include <cstdio>
#include <algorithm>
#define N 200010
using namespace std;
int m , head[N] , to[N] , next[N] , cnt , fa[N][20] , deep[N] , log[N] , opt[N] , x[N] , y[N] , c[N] , p[N];
int root[N] , ls[N * 20] , rs[N * 20] , si[N * 20] , tot;
void add(int x , int y)
{
to[++cnt] = y , next[cnt] = head[x] , head[x] = cnt;
}
void ins(int p , int l , int r , int x , int &y)
{
y = ++tot , si[y] = si[x] + 1;
if(l == r) return;
int mid = (l + r) >> 1;
if(p <= mid) rs[y] = rs[x] , ins(p , l , mid , ls[x] , ls[y]);
else ls[y] = ls[x] , ins(p , mid + 1 , r , rs[x] , rs[y]);
}
void dfs(int x)
{
int i;
if(p[x]) ins(p[x] , 1 , m , root[fa[x][0]] , root[x]);
else root[x] = root[fa[x][0]];
for(i = 1 ; i <= log[deep[x]] ; i ++ ) fa[x][i] = fa[fa[x][i - 1]][i - 1];
for(i = head[x] ; i ; i = next[i]) deep[to[i]] = deep[x] + 1 , dfs(to[i]);
}
int getlca(int x , int y)
{
int i;
if(deep[x] < deep[y]) swap(x , y);
for(i = log[deep[x] - deep[y]] ; ~i ; i -- )
if(deep[x] - (1 << i) >= deep[y])
x = fa[x][i];
for(i = log[deep[x]] ; ~i ; i -- )
if(deep[x] >= (1 << i) && fa[x][i] != fa[y][i])
x = fa[x][i] , y = fa[y][i];
return x == y ? x : fa[x][0];
}
int query(int p , int l , int r , int a , int b , int c , int d)
{
if(l == r) return si[a] + si[b] - si[c] - si[d];
int mid = (l + r) >> 1;
if(p <= mid) return query(p , l , mid , ls[a] , ls[b] , ls[c] , ls[d]);
else return query(p , mid + 1 , r , rs[a] , rs[b] , rs[c] , rs[d]) + si[ls[a]] + si[ls[b]] - si[ls[c]] - si[ls[d]];
}
int main()
{
int n , i , f;
scanf("%d%*d" , &n);
for(i = 2 ; i <= n ; i ++ ) scanf("%d" , &fa[i][0]) , add(fa[i][0] , i) , log[i] = log[i >> 1] + 1;
scanf("%d" , &m);
for(i = 1 ; i <= m ; i ++ )
{
scanf("%d%d" , &opt[i] , &x[i]);
if(opt[i] == 1) scanf("%d%d" , &y[i] , &c[i]);
else if(!p[x[i]]) p[x[i]] = i;
}
dfs(1);
for(i = 1 ; i <= m ; i ++ )
if(opt[i] == 1)
f = getlca(x[i] , y[i]) , printf("%d %d\n" , deep[x[i]] + deep[y[i]] - 2 * deep[f] + 1 , i - c[i] > 0 ? query(i - c[i] - 1 , 1 , m , root[x[i]] , root[y[i]] , root[f] , root[fa[f][0]]) : 0);
return 0;
}
【bzoj4448】[Scoi2015]情报传递 主席树的更多相关文章
- BZOJ4448[Scoi2015]情报传递——主席树+LCA
题目描述 奈特公司是一个巨大的情报公司,它有着庞大的情报网络.情报网络中共有n名情报员.每名情报员口J-能有 若T名(可能没有)下线,除1名大头目外其余n-1名情报员有且仅有1名上线.奈特公司纪律森严 ...
- bzoj4448 [Scoi2015]情报传递 主席树+树上差分
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4448 题解 练习一下主席树的基础练习题找回感觉. 对于每一次询问,第一问显然随便做. 第二问的 ...
- 【BZOJ4448】[Scoi2015]情报传递 主席树+LCA
[BZOJ4448][Scoi2015]情报传递 Description 奈特公司是一个巨大的情报公司,它有着庞大的情报网络.情报网络中共有n名情报员.每名情报员能有若干名(可能没有)下线,除1名大头 ...
- bzoj 4448 [Scoi2015]情报传递 主席树
比较套路的题目. 可以发现难点在于某个点的权值动态修改 且我们要维护树上一条路径上的点权>x的个数. 每个点都在动态修改 这意味着我们的只能暴力的去查每个点. 考虑将所有可以动态修改的点变成静态 ...
- 4448: [Scoi2015]情报传递|主席树|离线操作
能够把全部的操作离线,然后树链剖分将全部人搜集情报的时间增加到主席树中,查询的时候能够直接查询搜集情报时间≤i−C[i]−1的人的个数 时间复杂度n∗log22n,空间复杂度n∗log2n #incl ...
- BZOJ4448 SCOI2015情报传递(离线+树链剖分+树状数组)
即滋磁单点修改,询问路径上小于某数的值有多少个.暴力树剖套个主席树(或者直接树上主席树,似乎就1个log了?感觉不一定比两个log快)即可,然而不太优美. 开始觉得可以cdq,然而就变成log^3了. ...
- 洛谷P4216 [SCOI2015]情报传递(树剖+主席树)
传送门 我们可以进行离线处理,把每一个情报员的权值设为它开始收集情报的时间 那么设询问的时间为$t$,就是问路径上有多少个情报员的权值小于等于$t-c-1$ 这个只要用主席树上树就可以解决了,顺便用树 ...
- bzoj4448 SCOI2015 情报传递 message
传送门bzoj4448 题解 离线之后构建树上主席树,每个点的线段树维护到根路径的信息,不用链剖(我的链剖只是拿来求\(\mathrm{lca}\)的),时空复杂度\(O(n\log{n})\). c ...
- 2019.03.26 bzoj4448: [Scoi2015]情报传递(归并排序+树链剖分)
传送门 题意简述: 给一棵nnn个点的树,树上每个点表示一个情报员,一共有mmm天,每天会派发以下两种任务中的一个任务: 1.搜集情报:指派T号情报员搜集情报 2.传递情报:将一条情报从X号情报员传递 ...
随机推荐
- python_56_递归
在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数.(最大调用自己999次) def calc(n): print(n) if int(n/2)>0: retur ...
- IPv4与IPv6的校验函数
1. PHP校验IPv4掩码是否合法,在网上搜了下,排名最高的如下, <?php function is_mask($mask){ $bin_mask =(string)decbin(ip2lo ...
- wing ide 注释
ctrl-.是批量注视 ctrl->向前缩进 ctrl-<向后缩进
- 基于supersocket、C#对JT808协议进行解析构建gps监控平台服务端
GPS监控平台.车联网.物联网系统中GPRS网络数据的并发通讯和处理解析,主要功能有socket的UDP和TCP链路建立和维持,网络数据协议包接收与解析,分发上传到其他业务规则服务器,在物联网以及位置 ...
- 操作系统(6)_虚拟存储管理_李善平ppt
image含各种段. 有些不需要的页可能永远不需要装入内存,可能只有百分之70-80是异常情况采用的,这种代码就可以放入硬盘. 抖动实际就是进程数太多导致内存不够用造成的. 页面换入换出在内存和磁盘之 ...
- VS Code 用户自定义代码片段(React)
VS Code 用户自定义代码片段(React) .jsxReact组件模板:javascriptreact.json { "Import React": { "pref ...
- jrtplib库使用简解
RTP有效载荷类型即时间截解释 =============================== https://www.cnblogs.com/wyqfighting/archive/2013/03/ ...
- Redis之String类型操作
接口IRedisDaoStr: package com.net.test.redis.base.dao; import java.util.List; import java.util.Map; /* ...
- oracle insert用法总结
总结下Oracle 中的Insert用法 1.标准Insert --单表单行插入 语法: INSERT INTO table [(column1,column2,...)] VALUE ...
- 一个人的旅行 HDU - 2066 (最短路)
一个人的旅行 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Subm ...