[SCOI2015]情报传递[树剖+主席树]
题意大概就是 使得在 \(i\) 时刻加入一个情报员帮您传情报 然后询问 \(x,y,c\) 指 \(x\)到\(y\)多少个人有风险…(大于c)的都有风险…每天风险值+1
看起来…不太可做…
每次要整棵树+1复杂度也需要\(log^2\)的树套树吧
但是显然不用啊 查询的时候减掉就可以了…
所以直接树剖上面无脑主席树就可以了啊…
#include <bits/stdc++.h>
// #define int long long
#define rep(a , b , c) for(int a = b ; a <= c ; ++ a)
#define Rep(a , b , c) for(int a = b ; a >= c ; -- a)
#define go(u) for(int i = G.head[u] , v = G.to[i] , w = G.dis[i] ; i ; v = G.to[i = G.nxt[i]] , w = G.dis[i])
using namespace std ;
using ll = long long ;
using pii = pair < int , int > ;
using vi = vector < int > ;
int read() {
int x = 0 ; bool f = 1 ; char c = getchar() ;
while(c < 48 || c > 57) { if(c == '-') f = 0 ; c = getchar() ; }
while(c > 47 && c < 58) { x = (x << 1) + (x << 3) + (c & 15) ; c = getchar() ; }
return f ? x : -x ;
}
template <class T> void print(T x , char c = '\n') {
static char st[100] ; int stp = 0 ;
if(! x) { putchar('0') ; }
if(x < 0) { x = -x ; putchar('-') ; }
while(x) { st[++ stp] = x % 10 ^ 48 ; x /= 10 ; }
while(stp) { putchar(st[stp --]) ; } putchar(c) ;
}
template <class T> void cmax(T & x , T y) { x < y ? x = y : 0 ; }
template <class T> void cmin(T & x , T y) { x > y ? x = y : 0 ; }
const int _N = 1e6 + 10 ;
struct Group {
int head[_N] , nxt[_N << 1] , to[_N] , dis[_N] , cnt = 1 ;
Group () { memset(head , 0 , sizeof(head)) ; }
void add(int u , int v , int w = 1) { nxt[++ cnt] = head[u] ; to[cnt] = v ; dis[cnt] = w ; head[u] = cnt ; }
} G;
const int N = 2e5 + 10 ;
typedef int arr[N] ;
int n , q ;
arr X , Y , c , rt , sz , fa , son , d , val ;
int root = 0 ;
void dfs(int u) {
sz[u] = 1 ; go(u) {
d[v] = d[u] + 1 ;
dfs(v) ; sz[u] += sz[v] ;
if(sz[v] > sz[son[u]]) son[u] = v ;
}
}
int idx = 0 ;
arr top , id ;
void dfs(int u , int t){
top[u] = t ; id[u] = ++ idx ;
if(son[u]) dfs(son[u] , t) ;
go(u) if(v ^ son[u]) dfs(v , v) ;
}
int cnt = 0 ;
int ls[N << 5] , rs[N << 5] , sum[N << 5] ;
void upd(int pre , int & p , int l , int r , int pos) {
ls[p = ++ cnt] = ls[pre] ;
rs[p] = rs[pre] ;
sum[p] = sum[pre] + 1 ;
if(l == r) return ;
int mid = l + r >> 1 ;
pos <= mid ? upd(ls[pre] , ls[p] , l , mid , pos) : upd(rs[pre] , rs[p] , mid + 1 , r , pos) ;
}
int query(int L , int R , int l , int r , int x) {
if(l == r) return sum[R] - sum[L] ;
int mid = l + r >> 1 ;
if(x <= mid) return query(ls[L] , ls[R] , l , mid , x) ;
return sum[ls[R]] - sum[ls[L]] + query(rs[L] , rs[R] , mid + 1 , r , x) ;
}
void build(int u) {
upd(rt[fa[u]] , rt[u] , 1 , q , val[u]) ; go(u) build(v) ;
}
int Lca(int x , int y) {
while(top[x] != top[y]) {
if(d[top[x]] < d[top[y]]) swap(x , y) ;
x = fa[top[x]] ;
}
return d[x] < d[y] ? x : y ;
}
signed main() {
n = read() ;
rep(i , 1 , n) { fa[i] = read() ; if(! fa[i]) root = i ; else G.add(fa[i] , i) ; }
q = read() ;
rep(i , 1 , n) val[i] = q ;
rep(i , 1 , q) {
int op = read() ;
if(op == 1) X[i] = read() , Y[i] = read() , c[i] = read() ;
else val[read()] = i ;
}
dfs(root) ; dfs(root , root) ; build(root) ;
rep(i , 1 , q) {
if(! X[i]) continue ;
int lca = Lca(X[i] , Y[i]) ;
print(d[X[i]] + d[Y[i]] - (d[lca] << 1) + 1 , ' ') ;
if(i - c[i] - 1 <= 0) { print(0) ; continue ; }
print(query(rt[lca] , rt[X[i]] , 1 , q , i - c[i] - 1) + query(rt[lca] , rt[Y[i]] , 1 , q , i - c[i] - 1) + (val[lca] <= i - c[i] - 1)) ;
}
return 0 ;
}
[SCOI2015]情报传递[树剖+主席树]的更多相关文章
- BZOJ_2588_Spoj 10628. Count on a tree_树剖+主席树
BZOJ_2588_Spoj 10628. Count on a tree_树剖+主席树 题意: 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastan ...
- 洛谷P4216 [SCOI2015]情报传递(树剖+主席树)
传送门 我们可以进行离线处理,把每一个情报员的权值设为它开始收集情报的时间 那么设询问的时间为$t$,就是问路径上有多少个情报员的权值小于等于$t-c-1$ 这个只要用主席树上树就可以解决了,顺便用树 ...
- [HNOI2015]开店(树剖+主席树+标记永久化)
听说正解点分树?我不会就对了 此题是 \([LNOI2014]LCA\) 强化版,也是差分一下,转化为区间加区间和 不过权值有大小要求,那么我们按照权值排序,依次加入主席树,询问的时候 \(lower ...
- BZOJ3531-[Sdoi2014]旅行(树剖+线段树动态开点)
传送门 完了今天才知道原来线段树的动态开点和主席树是不一样的啊 我们先考虑没有宗教信仰的限制,那么就是一个很明显的树剖+线段树,路径查询最大值以及路径和 然后有了宗教信仰的限制该怎么做呢? 先考虑暴力 ...
- poj 2104 K-th Number 划分树,主席树讲解
K-th Number Input The first line of the input file contains n --- the size of the array, and m --- t ...
- 归并树 划分树 可持久化线段树(主席树) 入门题 hdu 2665
如果题目给出1e5的数据范围,,以前只会用n*log(n)的方法去想 今天学了一下两三种n*n*log(n)的数据结构 他们就是大名鼎鼎的 归并树 划分树 主席树,,,, 首先来说两个问题,,区间第k ...
- BZOJ_2238_Mst_树剖+线段树
BZOJ_2238_Mst_树剖+线段树 Description 给出一个N个点M条边的无向带权图,以及Q个询问,每次询问在图中删掉一条边后图的最小生成树.(各询问间独立,每次询问不对之后的询问产生影 ...
- BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树
BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树 Description 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为 ...
- BZOJ_2157_旅游_树剖+线段树
BZOJ_2157_旅游_树剖+线段树 Description Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但 ...
随机推荐
- 《Python学习手册 第五版》 -第13章 while循环和for循环
上一章已经讲过if条件语句,这章重点是循环语句:while.for 本章的重点内容 1.while循环 1)一般形式 2)break.continue.pass和循环的else 2.for循环 1)一 ...
- 第3章 JDK并发包(三)
3.2 线程复用:线程池 一种最为简单的线程创建和回收的方法类似如下代码: new Thread(new Runnable() { @Override public void run() { // d ...
- java中深拷贝浅拷贝简析
Java中对象的创建 clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象.所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象.那 ...
- android 基础学习笔记3
1.XML解析 与 Json 解析 (文件读取一般较耗时 可将相应的解析做成方法 用线程调用) 一.XML解析 (pull解析)res/xml(资源文件 需用到Resources) Xml文本 ...
- RFC笔记—Neighbor Discovery for IP version 6 (IPv6)
Router Solicitation Message Source Address An IP address assigned to the sending interface, or the u ...
- k8s Pipline CI/CD
一.Pipeline介绍 pipeline是一套jenkins官方提供的插件,它可以用来在jenkins中实现和集成连续交付 用户可以利用Pipeline的许多功能: 代码:pipeline在代码中实 ...
- 安装python 第三方库(whl,py格式)
注意:在python环境中输入 help('modules') 可以列出所有已经安装的模块 1.windows平台下: 1..1安装whl文件 安装 ...
- codewars--js--the highest and lowest number + JS 字符串和数组相关知识
本文参考: http://blog.csdn.net/tyrionj/article/details/78653426 http://www.runoob.com/jsref/jsref-obj-st ...
- redis中key键操作
keys */查看所有的key remoteSelf:1>select 0 "OK" remoteSelf:0>keys * 1) "SUBCRIBEMAP& ...
- Centos 7.5 搭建FTP配置虚拟用户
Centos 7.5 搭建FTP配置虚拟用户 1.安装vsftpd #vsftpd下载地址 http://mirror.centos.org/centos/7/os/x86_64/Packages/v ...