[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 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但 ...
随机推荐
- css 浏览兼容问题及解决办法 (2)
1.div的垂直居中问题 vertical-align:middle; 将行距增加到和整个DIV一样高 line-height:200px; 然后插入文字,就垂直居中了.缺点是要控制内容不要换行 2. ...
- cookie 笔记
Cookie “小甜点” Cookie的作用是与服务器进行交互,作为HTTP规范的一部分而存在 ,而Web Storage仅仅是为了在本地“存储”数据而生 用来记录:用户信息 计算机信息 浏 ...
- num09---建造者模式
建造者模式: 核心思想:将产品 和 产品建造过程解耦
- [redis读书笔记] 第一部分 数据结构与对象 链表
二 链表 1.链表节点使用ListNode结构,是一个双向的链表,同时,还实现了一个控制所有ListNode的结构list: typedef struct listNode { // 前置节点 str ...
- 一键安装apache-2.4.38脚本
[root@lamp scripts]# cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core) [root@lamp scripts ...
- Webpack之魔法注释/* webpackChunkName:"lodash" */的做用
之前在vue的路由配置文件中看到了/* webpackChunkName:"lodash" */这个注释, 在学习了webpack之后了解其做用,作用就是webpack在打包的时候 ...
- 怎么用IDEA快速查看类图关系
做Java开发的,现在普遍都用上idea了.可以说,idea是当之无愧的Java开发神器.如果,你现在还没用idea,那肯定是你还没有感受过它的强大. 好了,话不多说,今天的主题主要是教大家怎么通过i ...
- Vue中的递归组件
递归函数我们都再熟悉不过了,也就是函数自己调用自己.递归组件也是类似的,在组件的template内部使用组件自身.那递归组件有什么使用场景呢? 我们都知道树这个数据结构就是一种递归的结构,因此我们可以 ...
- 利用MySQL之federated引擎实现DBLink功能
有时候我们需要跨库join查询,但是配置多数据源成本又太高,Oracle提供了DBLink功能,MySQL中也有类似的实现:federated-engine. MySQL中使用federated引擎的 ...
- 07.JS对象-2
前言: 学习一门编程语言的基本步骤(01)了解背景知识(02)搭建开发环境(03)语法规范(04)常量和变量(05)数据类型(06)数据类型转换(07)运算符(08)逻辑结构(09)函数(10)对象1 ...