dfs序+主席树 或者 树链剖分+主席树(没写) 或者 线段树套线段树 或者 线段树套splay 或者 线段树套树状数组 bzoj 4448
4448: [Scoi2015]情报传递
Time Limit: 20 Sec Memory Limit: 256 MB
Submit: 588 Solved: 308
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
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
Sample Output
5 2
5 1
HINT
首先说明因为是寻找危险度大于C的,那么就相当于是往前面移动C天,因此我们就只需要寻找1~i-c-1就好了。然后也相当于每天都对某一个节点进行染色。当然,dfs序和树链剖分的最主要的思想还是要去重
思路一:dfs序+主席树,类似于bzoj 2588
每次都是按照:root[x] + root[y] - root[lca] - root[par[lca][0]]即可哦
//看看会不会爆int!数组会不会少了一维!
//取物问题一定要小心先手胜利的条件
#include <bits/stdc++.h>
using namespace std;
#pragma comment(linker,"/STACK:102400000,102400000")
#define LL long long
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define haha printf("haha\n")
const int maxn = 2e5 + ;
struct Tree{
int lnub, rnub, sum;
Tree(int l = , int r = , int s = ): lnub(l), rnub(r), sum(s){}
}tree[maxn * ];
int deep[maxn], par[maxn][], root[maxn], day[maxn];
vector<int> G[maxn];
int n, m, tot;
int ty[maxn], x[maxn], y[maxn], c[maxn];
/*
由于每次询问都是询问危险值为c的,所以我们就要往前面走c+1天,表示在c+1天之前染色的数目。
我们可以发现,我们只要储存每次特工的开始的时间就好了。然后离线查询即可发现
*/ int update(int o, int l, int r, int pos){
int k = ++tot;
tree[k] = tree[o]; tree[k].sum++;
if (l == r && l == pos) return k;
int mid = (l + r) / ;
if (pos <= mid) tree[k].lnub = update(tree[o].lnub, l, mid, pos);
if (pos > mid) tree[k].rnub = update(tree[o].rnub, mid + , r, pos);
return k;
} void dfs(int u, int fa, int road){
deep[u] = road; par[u][] = fa;
root[u] = root[fa];
if (day[u]) root[u] = update(root[fa], , m, day[u]);
for (int i = ; i <= ; i++){
if (road < ( << i)) break;
par[u][i] = par[par[u][i - ]][i - ];
}
for (int i = ; i < G[u].size(); i++){
int v = G[u][i];
if (v == fa) continue;
dfs(v, u, road + );
}
} int get_lca(int x, int y){
if (deep[x] < deep[y]) swap(x, y);
int delta = deep[x] - deep[y];
for (int i = ; i <= ; i++){
if (delta & ( << i)) x = par[x][i];
}
if (x == y) return x;
for (int i = ; i >= ; i--){
if (par[x][i] != par[y][i])
x = par[x][i], y = par[y][i];
}
return par[x][];
} int query(int o, int l, int r, int ql, int qr){
if (ql > qr) return ;
if (ql <= l && qr >= r) return tree[o].sum;
int ans = ;
int mid = (l + r) / ;
if (ql <= mid) ans += query(tree[o].lnub, l, mid, ql, qr);
if (qr > mid) ans += query(tree[o].rnub, mid + , r, ql, qr);
return ans;
} void solve(){
for (int i = ; i <= m; i++){
if (ty[i] == ){
int lca = get_lca(x[i], y[i]), old = par[lca][];
int ans = deep[x[i]] + deep[y[i]] - deep[lca] - deep[old];
printf("%d ", ans);
ans = ;
int k = i - c[i] - ;
ans += query(root[x[i]], , m, , k);
ans += query(root[y[i]], , m, , k);
ans -= query(root[lca], , m, , k);
if (old) ans -= query(root[old], , m, , k);
printf("%d\n", ans);
}
}
} int main(){
scanf("%d", &n);
int rt;
for (int i = ; i <= n; i++){
int fa; scanf("%d", &fa); int v = i;
if (fa == ){rt = i; continue;}
G[fa].pb(v), G[v].pb(fa);
}
scanf("%d", &m);
for (int i = ; i <= m; i++){
scanf("%d", ty + i);
if(ty[i] == )
scanf("%d%d%d", x + i, y + i, c + i);
else {
int T; scanf("%d", &T); day[T] = i;
}
}
dfs(rt, , );
solve();
return ;
}
思路二:树链剖分+主席树 (这玩意儿到现在没看懂,明天再弄)
主席树呢,是按照dfstime来对每个,root[i]保存的是目前dfstime的时间。然后所以每次询问呢,
都是query(root[pos[belong[x]] - 1]], root[pos[x]], 1, m, c)
思路三:线段树套线段树 = =还没看,在说吧
dfs序+主席树 或者 树链剖分+主席树(没写) 或者 线段树套线段树 或者 线段树套splay 或者 线段树套树状数组 bzoj 4448的更多相关文章
- 5.15 牛客挑战赛40 E 小V和gcd树 树链剖分 主席树 树状数组 根号分治
LINK:小V和gcd树 时限是8s 所以当时好多nq的暴力都能跑过. 考虑每次询问暴力 跳父亲 这样是nq的 4e8左右 随便过. 不过每次跳到某个点的时候需要得到边权 如果直接暴力gcd的话 nq ...
- BZOJ 4448: [Scoi2015]情报传递 树链剖分 主席树
4448: [Scoi2015]情报传递 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4448 Description 奈特公司是一个巨 ...
- HDU 5111 Alexandra and Two Trees 树链剖分 + 主席树
题意: 给出两棵树,每棵树的节点都有一个权值. 同一棵树上的节点的权值互不相同,不同树上节点的权值可以相同. 要求回答如下询问: \(u_1 \, v_1 \, u_2 \, v_2\):询问第一棵树 ...
- Codechef FIBTREE 树链剖分 主席树 LCA 二次剩余 快速幂
原文链接https://www.cnblogs.com/zhouzhendong/p/CC-FIBTREE.html 题目传送门 - CC-FIBTREE 题意 给定一个有 $n$ 个节点,初始点权都 ...
- BZOJ1146 [CTSC2008]网络管理Network 树链剖分 主席树 树状数组
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1146 题意概括 在一棵树上,每一个点一个权值. 有两种操作: 1.单点修改 2.询问两点之间的树链 ...
- bzoj 4448 [Scoi2015]情报传递 (树链剖分+主席树)
题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4448 题面: Description 奈特公司是一个巨大的情报公司,它有着庞大的情报网络 ...
- [GDOI2016][树链剖分+主席树]疯狂动物城
题面 Description Nick 是只在动物城以坑蒙拐骗为生的狐狸,儿时受到偏见的伤害,放弃了自己的理想.他被兔子 Judy 设下圈套,被迫与她合作查案,而卷入意想不到的阴谋,历尽艰险后成为搭档 ...
- BZOJ3531 SDOI2014 旅行 - 树链剖分,主席树
题意:给定一棵树,树上每个点有权值和类型.支持:修改某个点的类型:修改某个点的权值:询问某条链上某个类型的点的和/最大值.点数/类型数/询问数<=100000. 分析: 树链剖分,对每个类型的点 ...
- [FJOI2014]最短路径树问题 长链剖分
[FJOI2014]最短路径树问题 LG传送门 B站传送门 长链剖分练手好题. 如果你还不会长链剖分的基本操作,可以看看我的总结. 这题本来出的很没水平,就是dijkstra(反正我是不用SPFA)的 ...
随机推荐
- UVALive - 6916 Punching Robot Lucas+dp
题目链接: http://acm.hust.edu.cn/vjudge/problem/96344 Punching Robot Time Limit: 1000MS64bit IO Format: ...
- 【beta】Scrum站立会议第7次....11.9
小组名称:nice! 组长:李权 成员:于淼 刘芳芳韩媛媛 宫丽君 项目内容:约跑app(约吧) 时间:2016.11.9 12:00——12:30 地点:传媒西楼220室 本次对beta阶段 ...
- CentOS 7 U盘安装问题解决
最近期待以久的CentOS 7正式版终于发布了,在家里无聊,所以就打算在我的小Y上安装一下,由于笔记本原来有安装Windows 7 操作系统,考虑使用的需求,所以决定安装双系统: 1. ...
- Laravel中如何添加新字段,如何指定在某个字段后而不是添加在最后
解答:
- 微信小程序 跳坑
http://www.wxapp-union.com/forum.php?mod=viewthread&tid=3270
- 关于WPS页面横向问题
上图 即可进行横向竖向页面设置
- Thread的run()与start()的区别
java的线程是通过java.lang.Thread类来实现的.VM启动时会有一个由主方法所定义的线程.可以通过创建Thread的实例来创建新的线程.每个线程都是通过某个特定Thread对象所对应的方 ...
- Java多线程 -join用法
阿里面试官问我这个问题,我仔细总结了一下: 参考:sleep.yield.wait.join的区别(阿里面试) 1. join()介绍 join() 定义在Thread.java中.join() 的作 ...
- 第179天:javascript中replace使用总结
ECMAScript提供了replace()方法.这个方法接收两个参数,第一个参数可以是一个RegExp对象或者一个字符串,第二个参数可以是一个字符串或者一个函数.现在我们来详细讲解可能出现的几种情况 ...
- java finally 与return
finally之外的语句块有return,finally语句块没有return:该语句块的返回值被固定下来,等fianlly执行完后返回给调用者 finally语句块与其他语句块同时有return:返 ...