题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4448

题面:

Description

奈特公司是一个巨大的情报公司,它有着庞大的情报网络。情报网络中共有n名情报员。每名情报员口J-能有
若T名(可能没有)下线,除1名大头日外其余n-1名情报员有且仅有1名上线。奈特公司纪律森严,每
名情报员只能与自己的上、下线联系,同时,情报网络中仟意两名情报员一定能够通过情报网络传递情报。
奈特公司每天会派发以下两种任务中的一个任务:
1.搜集情报:指派T号情报员搜集情报
2.传递情报:将一条情报从X号情报员传递给Y号情报员
情报员最初处于潜伏阶段,他们是相对安全的,我们认为此时所有情报员的危险值为0;-旦某个情报员开
始搜集情报,他的危险值就会持续增加,每天增加1点危险值(开始搜集情报的当天危险值仍为0,第2天
危险值为1,第3天危险值为2,以此类推)。传递情报并不会使情报员的危险值增加。
为了保证传递情报的过程相对安全,每条情报都有一个风险控制值C。余特公司认为,参与传递这条情
报的所有情报员中,危险值大于C的情报员将对该条情报构成威胁。现在,奈特公司希望知道,对于每
个传递情报任务,参与传递的情报员有多少个,其中对该条情报构成威胁的情报员有多少个。

Input

第1行包含1个正整数n,表示情报员个数。
笫2行包含n个非负整数,其中第i个整数Pi表示i号情报员上线的编号。特别地,若Pi=0,表示i号
情报员是大头目。
第3行包含1个正整数q,表示奈特公司将派发q个任务(每天一个)。
随后q行,依次描述q个任务。
每行首先有1个正整数k。若k=1,表示任务是传递情报,随后有3个正整数Xi、Yi、Ci,依次表示传递
情报的起点、终点和风险控制值;若k=2,表示任务是搜集情报,随后有1个正整数Ti,表示搜集情报的
情报员编号。

Output

对于每个传递情报任务输出一行,应包含两个整数,分别是参与传递情报的情报员个数和对该条情报构成威胁的情报员个数。
输出的行数应等于传递情报任务的个数,每行仅包含两个整数,用一个空格隔开。输出不应包含多余的空行和空格。

Sample Input

7
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 0
5 2
5 1

HINT

对于3个传递情报任务,都是经过5名情报员,分别是4号、2号、1号、3号和7号。其中,对于第1个
任务,所有情报员(危险值为0)都不对情报构成威胁;对于第2个任务,有2名情报员对情报构成威胁,
分别是1号情报员(危险值为3)和4号情报员(危险值为2),7号情报员(危险值为1)并不构成威胁;
对于第3个任务,只有1名情报员对情报构成威胁。
n< = 2×10^5,Q< = 2×105,0< Pi,C!< = N, 1< = Ti,Xi,Yi< = n
思路:
这道题题意很好理解,就不说了,,
我们可以将k = 2的操作全部离线处理掉,对于k = 1的操作我们需要输出两个值:第一个值:两点间经过多少个点。。。这个树剖剖完后树就变成了一段区间,要求【x,y】区间的值
我们可以用【1,x】区间加上【1,y】区间减去两倍的【1,min(x,y)】区间再+1就好了,,如果看不懂可以去画下图就好了;
求第二个值我们只要在链(x,y)上找到所有 小于等于 i - ci - 1 的值就好了,这里用主席树区间查询下就好了。
写法:先用树链剖分将这棵树变成线性结构再用主席树处理下就好了。
 
实现代码:
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. #define lson l,m,rt<<1
  4. #define rson m+1,r,rt<<1|1
  5. #define mid int m = (l + r) >> 1
  6. const int M = 2e5+;
  7. const int Max = 5e6+;
  8. struct node{
  9. int to,next;
  10. }e[M<<];
  11. int head[M];
  12. int dep[M],fa[M],siz[M],son[M],top[M],tid[M],rk[M],cnt,cnt1;
  13. int ls[Max],rs[Max],sum[Max],root[Max],idx,n,q,t[M];
  14. void add(int u,int v){
  15. e[++cnt1].to = v; e[cnt1].next = head[u];head[u] = cnt1;
  16. }
  17.  
  18. void dfs1(int u,int faz,int deep){
  19. dep[u] = deep;
  20. fa[u] = faz;
  21. siz[u] = ;
  22. for(int i = head[u];i;i = e[i].next){
  23. int v = e[i].to;
  24. if(v != fa[u]){
  25. dfs1(v,u,deep+);
  26. siz[u] += siz[v];
  27. if(son[u] == -||siz[v] > siz[son[u]])
  28. son[u] = v;
  29. }
  30. }
  31. }
  32.  
  33. void dfs2(int u,int t){
  34. top[u] = t;
  35. tid[u] = cnt;
  36. rk[cnt] = u;
  37. cnt++;
  38. if(son[u] == -) return ;
  39. dfs2(son[u],t);
  40. for(int i = head[u];i;i = e[i].next){
  41. int v = e[i].to;
  42. if(v != son[u]&&v != fa[u])
  43. dfs2(v,v);
  44. }
  45. }
  46.  
  47. void update(int old,int &k,int l,int r,int p){
  48. k = ++idx;
  49. ls[k] = ls[old]; rs[k] = rs[old]; sum[k] = sum[old] + ;
  50. if(l == r) return ;
  51. mid;
  52. if(p <= m) update(ls[old],ls[k],l,m,p);
  53. else update(rs[old],rs[k],m+,r,p);
  54. }
  55.  
  56. int query(int L,int R,int l,int r,int p){
  57. L = root[L - ], R = root[R];
  58. int ret = ;
  59. while(l != r){
  60. mid;
  61. if(p <= m) L = ls[L] ,R = ls[R], r = m;
  62. else ret += sum[ls[R]] - sum[ls[L]],L = rs[L],R = rs[R],l = m+;
  63. }
  64. if(p >= l) ret += sum[R] - sum[L];
  65. return ret;
  66. }
  67.  
  68. int solve(int x,int y,int p){
  69. int ans = ; int fx = top[x],fy = top[y];
  70. int tmp = dep[x] + dep[y];
  71. while(fx != fy){
  72. if(dep[fx] < dep[fy]) swap(x,y),swap(fx,fy);
  73. ans += query(tid[fx],tid[x],,q,p);
  74. x = fa[fx]; fx = top[x];
  75. }
  76. if(dep[x] > dep[y]) swap(x,y);
  77. ans += query(tid[x],tid[y],,q,p);
  78. cout<<tmp - *dep[x] + <<" "<<ans<<endl;
  79. }
  80. int x,k,w,u[M],v[M],c[M];
  81. int main()
  82. {
  83. ios::sync_with_stdio();
  84. cin.tie(); cout.tie();
  85. memset(son,-,sizeof(son));
  86. cin>>n;
  87. for(int i = ;i <= n;i ++){
  88. cin>>x; add(x,i);
  89. }
  90. dfs1(,-,); dfs2(,);
  91. cin>>q;
  92. memset(t,q,sizeof(t));
  93. int cnt2 = ;
  94. for(int i = ;i <= n;i ++) t[i] = q;
  95. for(int i = ;i <= q;i ++){
  96. cin>>k;
  97. if(k == ){
  98. cin>>u[cnt2]>>v[cnt2]>>w;
  99. c[cnt2++] = i - w - ;
  100. }
  101. else
  102. cin>>x,t[x] = i;
  103. }
  104. for(int i = ;i <= n;i ++)
  105. update(root[i-],root[i],,q,t[rk[i]]);
  106. for(int i = ;i < cnt2;i ++)
  107. solve(u[i],v[i],c[i]);
  108. }

bzoj 4448 [Scoi2015]情报传递 (树链剖分+主席树)的更多相关文章

  1. dfs序+主席树 或者 树链剖分+主席树(没写) 或者 线段树套线段树 或者 线段树套splay 或者 线段树套树状数组 bzoj 4448

    4448: [Scoi2015]情报传递 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 588  Solved: 308[Submit][Status ...

  2. BZOJ 4448: [Scoi2015]情报传递 树链剖分 主席树

    4448: [Scoi2015]情报传递 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4448 Description 奈特公司是一个巨 ...

  3. Codechef FIBTREE 树链剖分 主席树 LCA 二次剩余 快速幂

    原文链接https://www.cnblogs.com/zhouzhendong/p/CC-FIBTREE.html 题目传送门 - CC-FIBTREE 题意 给定一个有 $n$ 个节点,初始点权都 ...

  4. BZOJ1146 [CTSC2008]网络管理Network 树链剖分 主席树 树状数组

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1146 题意概括 在一棵树上,每一个点一个权值. 有两种操作: 1.单点修改 2.询问两点之间的树链 ...

  5. [GDOI2016][树链剖分+主席树]疯狂动物城

    题面 Description Nick 是只在动物城以坑蒙拐骗为生的狐狸,儿时受到偏见的伤害,放弃了自己的理想.他被兔子 Judy 设下圈套,被迫与她合作查案,而卷入意想不到的阴谋,历尽艰险后成为搭档 ...

  6. HDU 5111 Alexandra and Two Trees 树链剖分 + 主席树

    题意: 给出两棵树,每棵树的节点都有一个权值. 同一棵树上的节点的权值互不相同,不同树上节点的权值可以相同. 要求回答如下询问: \(u_1 \, v_1 \, u_2 \, v_2\):询问第一棵树 ...

  7. 5.15 牛客挑战赛40 E 小V和gcd树 树链剖分 主席树 树状数组 根号分治

    LINK:小V和gcd树 时限是8s 所以当时好多nq的暴力都能跑过. 考虑每次询问暴力 跳父亲 这样是nq的 4e8左右 随便过. 不过每次跳到某个点的时候需要得到边权 如果直接暴力gcd的话 nq ...

  8. BZOJ3531 SDOI2014 旅行 - 树链剖分,主席树

    题意:给定一棵树,树上每个点有权值和类型.支持:修改某个点的类型:修改某个点的权值:询问某条链上某个类型的点的和/最大值.点数/类型数/询问数<=100000. 分析: 树链剖分,对每个类型的点 ...

  9. BZOJ4012 HNOI2015开店(树链剖分+主席树)

    考虑这样一个问题:一棵树初始全是白点,有两种操作:把一个点染黑:询问某点到所有黑点的距离之和. 注意到树上两点x和y的距离为depth[x]+depth[y]-depth[lca(x,y)]*2.要求 ...

随机推荐

  1. jqgrid 分页时,清空原表格数据加载返回的新数据

    由于,我们是动态分页,分页后的数据是在触发分页后动态加载而来.如何使jqgrid清空原数据而加载新数据? 1)调用jqgrid的 clearGridData 方法清空表格数据 2)调用jqgrid的  ...

  2. Excel frequency函数

    计算连续次数最常用的函数就是FREQUENCY,下面就这个函数在计算连续次数的应用做一个详细图解.首先,我们需要了解一下FREQUENCY函数的计算原理.    FREQENCY(数据区域,用于设置区 ...

  3. Docker的Mysql数据库:把数据存储在本地目录

    Docker mysql 把数据存储在本地目录,很简单,只需要映射本地目录到容器即可 1.加上-v参数 $ docker run -d -e MYSQL_ROOT_PASSWORD=admin --n ...

  4. bundle install 安装的 gem 提示 cannot load such file

    /usr/local/lib/ruby/site_ruby/2.1.0/rubygems/core_ext/kernel_require.rb:54:in `require': cannot load ...

  5. Java入门知识1

    1. 获取标准屏幕的输入时,需导入java.util.Scanner包. 2. 主类的名称与.java的文件名需一致. 3. 文件中主类设置为public,其他类前面无需加访问级别. 4. 继承时,使 ...

  6. pandas 初识(三)

    Python Pandas 空值 pandas 判断指定列是否(全部)为NaN(空值) import pandas as pd import numpy as np df = pd.DataFrame ...

  7. GitLab篇之Linux下环境搭建

    之前公司一直在使用微软的VSS和SVN做为源代码管理工具,考虑到VSS和SVN的局限性,个人一直建议我们应该采用Git来管理我们的源代码.Git的好处不多说相信大家也都知道的.Git不仅仅是一个源代码 ...

  8. 三丰云使用记录--部署iis服务器

     写在前面的话:看在我这么热心写使用推广记录,麻烦延长下使用天数,谢谢 官网地址:https://www.sanfengyun.com 三丰云是北京太极三丰云计算有限公司旗下网络服务品牌,十八年IDC ...

  9. Shell 基础 -- 总结几种括号、引号的用法

    Shell 脚本中经常需要用到一些括号.引号表达式,功能各不相同,本文详细介绍一下. 1.双引号 " " 双引号常用于包含一组字符串,在双引号中,除了 "$". ...

  10. 怎么用JavaScript写一个区块链?

    几乎所有语言都可以编写区块链开发程序.那么如何用JavaScript写一个区块链?以下我将要用JavaScript来创建1个简单的区块链来演示它们的内部到底是怎样工作的.我将会称作SavjeeCoin ...