「SCOI2015」情报传递
「SCOI2015」情报传递
题目描述
奈特公司是一个巨大的情报公司,它有着庞大的情报网络。情报网络中共有 \(n\) 名情报员。每名情报员可能有若干名(可能没有)下线,除 \(1\) 名大头目外其余 \(n - 1\) 名情报员有且仅有 \(1\) 名上线。奈特公司纪律森严,每名情报员只能与自己的上、下线联系,同时,情报网络中仟意两名情报员一定能够通过情报网络传递情报。
奈特公司每天会派发以下两种任务中的一个任务:
- 搜集情报:指派 \(T\) 号情报员搜集情报;
- 传递情报:将一条情报从 \(X\) 号情报员传递给 \(Y\) 号情报员。
情报员最初处于潜伏阶段,他们是相对安全的,我们认为此时所有情报员的危险值为 \(0\);一旦某个情报员开始搜集情报,他的危险值就会持续增加,每天增加 \(1\) 点危险值。传递情报并不会使情报员的危险值增加。
为了保证传递情报的过程相对安全,每条情报都有一个风险控制值 \(C\)。余特公司认为,参与传递这条情报的所有情报员中,危险值大于 \(C\) 的情报员将对该条情报构成威胁。现在,奈特公司希望知道,对于每个传递情报任务,参与传递的情报员有多少个,其中对该条情报构成威胁的情报员有多少个。
\(n≤2×10^5,Q≤2×10^5,0<P_i,C_i≤N,1≤T_i,X_i,Y_i≤n\)
解题思路 :
观察发现,只有在第 $ i-C_i-1$ 天之前搜集情报的节点才可能对答案产生贡献
那么问题就转化为点权 $+1 $,和求某一时刻树上一条链上的点权和
比较简单的做法就是将询问离线下来树链剖分即可,复杂度是 $O(nlog^2n) $,而且不能做强制在线
考虑到询问某一时刻其实就是访问历史版本,那么只需要对树上的点权信息进行可持久化即可
记 \(sum_i\) 表示某一时刻 \(i\) 到 \(root\) 的路径的点权和,那么答案就是 \(sum_x + sum_y - sum_{lca} - sum_{fa(lca)}\)
也就是说只要对 \(sum\) 数组可持久化就好了,显然每一次新建一个版本时一个子树的点权都会 \(+1\) ,这东西在 \(dfn\) 序上是一段连续的区间,直接 \(ins\) 即可,总复杂度是 $O(nlogn) $
/*program by mangoyang*/
#include<bits/stdc++.h>
#define inf (0x7f7f7f7f)
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
typedef long long ll;
using namespace std;
template <class T>
inline void read(T &x){
int f = 0, ch = 0; x = 0;
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = 1;
for(; isdigit(ch); ch = getchar()) x = x * 10 + ch - 48;
if(f) x = -x;
}
#define fi first
#define se second
const int N = 200005;
vector<int> g[N];
int rt[N], sz[N], ds[N], dep[N], dfn[N], f[N][21], vis[N], n, m, cnt, root;
namespace Prework{
inline void dfs(int u, int fa){
sz[u] = 1, f[u][0] = fa, dep[u] = dep[fa] + 1, dfn[u] = ++cnt;
for(int i = 0; i < g[u].size(); i++)
if(g[u][i] != fa) dfs(g[u][i], u), sz[u] += sz[g[u][i]];
}
inline void realmain(){
dfs(root, 0);
for(int j = 1; j <= 20; j++)
for(int i = 1; i <= n; i++) f[i][j] = f[f[i][j-1]][j-1];
}
}
inline pair<int, int> Getpath(int x, int y){
if(dep[x] < dep[y]) swap(x, y);
for(int i = 20; ~i; i--){
if(dep[f[x][i]] >= dep[y]) x = f[x][i];
if(dep[x] == dep[y]) break;
}
if(x == y) return make_pair(x, f[x][0]);
for(int i = 20; ~i; i--)
if(f[x][i] != f[y][i]) x = f[x][i], y = f[y][i];
return make_pair(f[x][0], f[f[x][0]][0]);
}
struct SegmentTree{
struct Node{ int lc, rc, add; } T[N*50]; int size;
inline void ins(int &u, int pr, int l, int r, int L, int R){
T[u=++size] = T[pr];
if(l >= L && r <= R) return (void) (T[u].add++);
int mid = l + r >> 1;
if(L <= mid) ins(T[u].lc, T[pr].lc, l, mid, L, R);
if(mid < R) ins(T[u].rc, T[pr].rc, mid + 1, r, L, R);
}
inline int query(int u, int l, int r, int pos){
if(l == r) return T[u].add;
int mid = l + r >> 1, res = 0;
if(pos <= mid) res += query(T[u].lc, l, mid, pos);
else res += query(T[u].rc, mid + 1, r, pos);
return res + T[u].add;
}
}van;
inline int calc(int x, int y){
if(!dfn[y] || !ds[x]) return 0;
return van.query(rt[ds[x]], 1, n, dfn[y]);
}
int main(){
read(n);
for(int i = 1, x; i <= n; i++){
read(x);
if(x) g[x].push_back(i), g[i].push_back(x); else root = i;
}
Prework::realmain();
read(m);
for(int i = 1, op, x, y, z; i <= m; i++){
read(op), read(x);
if(op == 1){
ds[i] = ds[i-1], read(y), read(z); int t = Max(i - z - 1, 0);
pair<int, int> now = Getpath(x, y);
int res = calc(t, x) + calc(t, y) - calc(t, now.fi) - calc(t, now.se);
printf("%d %d\n", dep[x] + dep[y] - dep[now.fi] - dep[now.se], res);
}
else{
if(vis[x]){ ds[i] = ds[i-1]; continue; }
ds[i] = ds[i-1] + 1, vis[x] = 1;
van.ins(rt[ds[i]], rt[ds[i-1]], 1, n, dfn[x], dfn[x] + sz[x] - 1);
}
}
return 0;
}
「SCOI2015」情报传递的更多相关文章
- AC日记——「SCOI2015」情报传递 LiBreOJ 2011
#2011. 「SCOI2015」情报传递 思路: 可持久化树状数组模板: 代码: #include <bits/stdc++.h> using namespace std; #defin ...
- 【LOJ】 #2011. 「SCOI2015」情报传递
题解 一写过一交A的一道数据结构水题 我们发现大于C可以转化为这条路径上有多少个在某天之前开始调查的情报员,离线全部读入,变成树上路径查询某个区间的数出现过多少次,构建一棵根缀的主席树,查询的时候用两 ...
- 「SCOI2015」小凸想跑步 解题报告
「SCOI2015」小凸想跑步 最开始以为和多边形的重心有关,后来发现多边形的重心没啥好玩的性质 实际上你把面积小于的不等式列出来,发现是一次的,那么就可以半平面交了 Code: #include & ...
- 「SCOI2015」国旗计划 解题报告
「SCOI2015」国旗计划 蛮有趣的一个题 注意到区间互不交错,那么如果我们已经钦定了一个区间,它选择的下一个区间是唯一的,就是和它有交且右端点在最右边的,这个可以单调队列预处理一下 然后往后面跳拿 ...
- 「SCOI2015」小凸解密码 解题报告
「SCOI2015」小凸解密码 题意:给一个环,定义一段连续的极长\(0\)串为\(0\)区间,定义一个位置的离一个\(0\)区间的距离为这个位置离这个区间中\(0\)的距离的最小值,每次询问一个位置 ...
- 「SCOI2015」小凸玩矩阵 解题报告
「SCOI2015」小凸玩矩阵 我好沙茶啊 把点当边连接行和列,在外面二分答案跑图的匹配就行了 我最开始二分方向搞反了,样例没过. 脑袋一抽,这绝壁要费用流,连忙打了个KM 然后wa了,一想这个不是完 ...
- 「SCOI2015」小凸玩密室 解题报告
「SCOI2015」小凸玩密室 虽然有心里在想一些奇奇怪怪的事情的原因,不过还是写太久了.. 不过这个题本身也挺厉害的 注意第一个被点亮的是任意选的,我最开始压根没注意到 \(dp_{i,j}\)代表 ...
- loj#2009.「SCOI2015」小凸玩密室
题目链接 loj#2009. 「SCOI2015」小凸玩密室 题解 树高不会很高<=20 点亮灯泡x,点亮x的一个子树,再点亮x另外的子树, 然后回到x的父节点,点亮父节点之后再点亮父节点的其他 ...
- LibreOJ #2006. 「SCOI2015」小凸玩矩阵 二分答案+二分匹配
#2006. 「SCOI2015」小凸玩矩阵 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据 题目描述 ...
随机推荐
- 正则表达式:Python 模块 re 简介
为了使文章更具可读性,本文将正则表达式冗长的 语法介绍 放在了文章的末尾. 一.正则表达式简介 正则表达式(RegExp)是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(元字符 ...
- Java 9 中的 9 个新特性
Java 8 发布三年多之后,java9已经发布了 . 你可能已经听说过 Java 9 的模块系统,但是这个新版本还有许多其它的更新. 这里有九个令人兴奋的新功能将与 Java 9 一起发布. 1 ...
- canvas 绘制星座图(好玩)--转载
<!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8" ...
- Go Web 编程 第一章 Web相关概念
第一章 Go与Web应用 Go学习群:415660935 1.1 Web应用 在计算机的世界里,应用(application)是一个与用户进行交互,并完成用户特定任务的软件程序.而Web应用则是部署在 ...
- isolation forest进行异常点检测
一.简介 孤立森林(Isolation Forest)是另外一种高效的异常检测算法,它和随机森林类似,但每次选择划分属性和划分点(值)时都是随机的,而不是根据信息增益或者基尼指数来选择.在建树过程中, ...
- BBScan — 一个信息泄漏批量扫描脚本
github:https://github.com/lijiejie/BBScan 有些朋友手上有几十万甚至上百万个域名,比如,乌云所有厂商的子域名. 如果把这30万个域名全部扔给wvs,APPsca ...
- 记一个多线程使用libevent的问题
前段时间使用libevent网络库实现了一个游戏服务器引擎,在此记录下其中遇到的一个问题. 我在设计服务器上选择把逻辑和网络分线程,线程之间通信使用队列.但是这样做会有个问题: 当逻辑线程想要主动的发 ...
- 内存不够清理方法,costdown项目时如果裁剪不下来,也可以参考
Linux下清理内存和Cache方法 /proc/sys/vm/drop_caches 频繁的文件访问会导致系统的Cache使用量大增 $ free -m total used free shared ...
- linux配置samba服务【原创】
转载请注明出处http://www.cnblogs.com/paul8339/p/7509981.html 需求,windows服务器访问linux的共享文件,需要linux服务器安装并配置samba ...
- elasticsearch集群介绍及优化【转】
elasticsearch用于构建高可用和可扩展的系统.扩展的方式可以是购买更好的服务器(纵向扩展)或者购买更多的服务器(横向扩展),Elasticsearch能从更强大的硬件中获得更好的性能,但是纵 ...