[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 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但 ...
随机推荐
- Mario是一个基于.NETCore的简单快速开发框架
Mario .NET Core简单快速开发框架 Mario是一个基于.NET Core的简单快速开发框架 GitHub:https://github.com/deeround/Mario 技术特点 基 ...
- 《Head first设计模式》之命令模式
命令模式将"请求"封装成对象,以便使用不同的请求.队列或者日志来参数化其他对象.命令模式也支持可撤销的操作. 一个家电公司想邀请你设计一个家电自动化遥控器的API.这个遥控器有7个 ...
- php 搭建webSocket
<?php //2.设计一个循环挂起WebSocket通道,进行数据的接收.处理和发送 //对创建的socket循环进行监听,处理数据 function run(){ //死循环,直到socke ...
- Language Model
在某次会上的语言模型的ppt.
- [Python]Bytes 和 String转换
#----string to bytes------ # 方法一:直接复制bytes类型 b'<str>' b = b'Hello World' print(type(b)) print( ...
- HDU 1006 模拟
Tick and Tick Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
- linux内核编译 fatal error: openssl/opensslv.h: No such file or directory
ubuntu下缺少了的组件,安装即可: sudo apt-get install libssl-dev
- 修饰符 public、 private 和 protected和区别
TypeScript 可以使用三种访问修饰符(Access Modifiers),分别是 public.private 和 protected. public 修饰的属性或方法是公有的,可以在任何地方 ...
- typeof和类型转换
编程形式 ① 面向过程 ② 面向对象 ③ Js既面向过程又面向对象 typeof(数据) 1)typeof(数据)返回该数据是什么类型的 2)写法: ① typeof(数据) ② typeof 数据 ...
- 基于已构建S2SH项目配置全注解方式简化配置文件
如果还不熟悉s2sh项目搭建的朋友可以先阅读 eclipse环境下基于tomcat-7.0.82构建struts2项目 eclipse环境下基于已构建struts2项目整合spring+hiberna ...