【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号情报员传递 ...
随机推荐
- numpy.mean
http://docs.scipy.org/doc/numpy/reference/generated/numpy.mean.html numpy.mean(a, axis=None, dtype=N ...
- 操作表单 -------JavaScrip
本文摘要:http://www.liaoxuefeng.com/ HTML表单的输入控件主要有以下几种: 文本框,对应的<input type="text">,用于输入 ...
- 漫谈Ajax在.Net中的使用
引用地址:http://birdshover.cnblogs.com/archive/2006/07/03/441439.html AJAX出来的时间也不短了.虽然它在某些方面很受争议,但是瑕不掩瑜. ...
- vue2.0中ckeckbox(复选框)的使用心得,及对click事件和change的理解
最近在公司项目中使用vue2.0做开发,在使用checkbox时遇到了一些问题,首先我们先了解一下需求. 如上如所示,在上方复选框被点击时,更改下方p标签的文本内容为:复选框已被选中.并将p标签文字颜 ...
- 题解 P3367 【【模板】并查集】
#include<iostream> #include<cstdio> using namespace std; int n,m,x,y,z; ]; //f[i]表示i的祖先 ...
- kubernetes搭建dashboard-v1.10.1
一键部署脚本(或者可使用helm安装): wget https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/ ...
- CSS 实现单行、多行文本溢出显示省略号
单行溢出 width:200px; overflow:hidden; text-overflow:ellipsis; -o-text-overflow:ellipsis; -webkit-text-o ...
- JZOJ 5776. 【NOIP2008模拟】小x游世界树
5776. [NOIP2008模拟]小x游世界树 (File IO): input:yggdrasil.in output:yggdrasil.out Time Limits: 1500 ms Me ...
- python 斗图图片爬虫
捣鼓了三小时,有一些小Bug,望大佬指导 废话不说,直接上代码: #!/usr/bin/python3 # -*- coding:UTF-8 -*- import os,re,requests fro ...
- django_mysql_配置
配置 1. 安装Pymysql pip install PyMySQL 然后在项目同名_init__添加 from pymysql import install_as_MySQLdb install_ ...