P3979 遥远的国度 树剖

题面

需要想一下的树剖题,对于询问三需要处理换跟后的情况。我们以1为树根跑一遍剖分,对于换跟进行分类讨论,算出实际答案。讨论有三种情况:

(以1为树根的树上)

  • 跟在询问节点的祖先上:因为不影响,所以直接求子树最小值

  • 跟即询问节点:直接查全树

  • 跟在询问节点子树中:画图容易得出,此时询问节点范围包含全树除了\(son\)的子树,其中\(son\)为跟向上跳达到询问节点的上一个节点。于是我们除去线段树区间\([idx[son], idx[son]+sz[son]-1]\)分左右区间讨论就好了。

  1. #include <cstdio>
  2. #include <algorithm>
  3. #define MAXN 100010
  4. #define ll long long
  5. #define sl (x<<1)
  6. #define sr (x<<1|1)
  7. using namespace std;
  8. int head[MAXN],vv[MAXN*2],nxt[MAXN*2],tot;
  9. const int INF=0x3fffffff;
  10. inline void add_edge(int u, int v){
  11. vv[++tot]=v;
  12. nxt[tot]=head[u];
  13. head[u]=tot;
  14. }
  15. int nod_val[MAXN];
  16. int mxs[MAXN],sz[MAXN],dep[MAXN];
  17. int f[MAXN][20];
  18. void dfs1(int u, int fa){
  19. dep[u]=dep[fa]+1;
  20. f[u][0]=fa;
  21. for(int i=1;i<=17;++i)
  22. f[u][i]=f[f[u][i-1]][i-1];
  23. sz[u]=1;
  24. int mxsz=-1;
  25. for(int i=head[u];i;i=nxt[i]){
  26. int v=vv[i];
  27. if(v==fa) continue;
  28. dfs1(v, u);
  29. sz[u]+=sz[v];
  30. if(mxsz<sz[v]){
  31. mxsz=sz[v];
  32. mxs[u]=v;
  33. }
  34. }
  35. }
  36. int idx[MAXN],topf[MAXN],cnt,wnew[MAXN];
  37. void dfs2(int u, int top){
  38. idx[u]=++cnt;
  39. topf[u]=top;
  40. wnew[cnt]=nod_val[u];
  41. if(mxs[u]==0) return;
  42. dfs2(mxs[u], top);
  43. for(int i=head[u];i;i=nxt[i]){
  44. int v=vv[i];
  45. if(v==f[u][0]||v==mxs[u]) continue;
  46. dfs2(v, v);
  47. }
  48. }
  49. struct nod{
  50. int l, r;
  51. int val,lazy;
  52. } tre[MAXN*4];
  53. void buildt(int x, int l, int r){
  54. tre[x].l=l,tre[x].r=r,tre[x].lazy=0;
  55. if(l==r){
  56. tre[x].val=wnew[l];
  57. return;
  58. }
  59. int mid=(l+r)>>1;
  60. buildt(sl, l, mid);
  61. buildt(sr, mid+1, r);
  62. tre[x].val=min(tre[sl].val, tre[sr].val);
  63. }
  64. void push_down(int x){
  65. if(tre[x].lazy==0) return;
  66. tre[sl].lazy=tre[sl].val=tre[x].lazy;
  67. tre[sr].lazy=tre[sr].val=tre[x].lazy;
  68. tre[x].lazy=0;
  69. }
  70. void change(int x, int l, int r, int val){
  71. if(l<=tre[x].l&&tre[x].r<=r){
  72. tre[x].lazy=tre[x].val=val;
  73. return;
  74. }
  75. push_down(x);
  76. int mid=(tre[x].l+tre[x].r)>>1;
  77. if(l<=mid) change(sl, l, r, val);
  78. if(mid<r) change(sr, l, r, val);
  79. tre[x].val=min(tre[sl].val, tre[sr].val);
  80. }
  81. int query(int x, int l, int r){
  82. if(l<=tre[x].l&&tre[x].r<=r){
  83. return tre[x].val;
  84. }
  85. push_down(x);
  86. int mid=(tre[x].l+tre[x].r)>>1;
  87. int ans=INF;
  88. if(l<=mid) ans=min(query(sl, l, r), ans);
  89. if(mid<r) ans=min(query(sr, l, r), ans);
  90. return ans;
  91. }
  92. void tre_change(int a, int b, int val){
  93. while(topf[a]!=topf[b]){
  94. if(dep[topf[a]]<dep[topf[b]]) swap(a,b);
  95. change(1, idx[topf[a]], idx[a], val);
  96. a=f[topf[a]][0];
  97. }
  98. if(dep[a]<dep[b]) swap(a,b);
  99. change(1, idx[b], idx[a], val);
  100. }
  101. int tre_lca(int a, int b){
  102. while(topf[a]!=topf[b]){
  103. if(dep[topf[a]]<dep[topf[b]]) swap(a,b);
  104. a=f[topf[a]][0];
  105. }
  106. if(dep[a]<dep[b]) return a;
  107. return b;
  108. }
  109. int tre_query(int a){
  110. return query(1, idx[a], idx[a]+sz[a]-1);
  111. }
  112. int get_son(int a, int b){
  113. for(int i=17;i>=0;--i)
  114. if(dep[f[b][i]]>dep[a]) b=f[b][i];
  115. return b;
  116. }
  117. int n,q,cap;
  118. int main()
  119. {
  120. scanf("%d %d", &n, &q);
  121. for(int i=1;i<n;++i){
  122. int a,b;
  123. scanf("%d %d", &a, &b);
  124. add_edge(a, b);
  125. add_edge(b, a);
  126. }
  127. for(int i=1;i<=n;++i) scanf("%d", &nod_val[i]);
  128. scanf("%d", &cap);
  129. dfs1(1, 1);
  130. dfs2(1, 1);
  131. buildt(1, 1, n);
  132. while(q--){
  133. int opt;
  134. scanf("%d", &opt);
  135. if(opt==1){
  136. scanf("%d", &cap);
  137. }else if(opt==2){
  138. int l,r,v;
  139. scanf("%d %d %d", &l, &r, &v);
  140. tre_change(l, r, v);
  141. }else if(opt==3){
  142. int t;
  143. scanf("%d", &t);
  144. int lca=tre_lca(t, cap);
  145. if(t==cap) printf("%d\n", query(1, 1, n));
  146. else if(lca!=t) printf("%d\n", tre_query(t));
  147. else{
  148. int son=get_son(t, cap);
  149. int ans=min(query(1, 1, idx[son]-1), query(1, idx[son]+sz[son], n)); // 除去中间那个区间,分左右区间求
  150. printf("%d\n", ans);
  151. }
  152. }else puts("Erro!");
  153. }
  154. return 0;
  155. }

P3979 遥远的国度 树剖的更多相关文章

  1. 洛谷P3979 遥远的国度 树链剖分+分类讨论

    题意:给出一棵树,这棵树每个点有权值,然后有3种操作.操作一:修改树根为rt,操作二:修改u到v路径上点权值为w,操作三:询问以rt为根x子树的最小权值. 解法:如果没有修改树根操作那么这题就是树链剖 ...

  2. BZOJ 3083: 遥远的国度 (树剖+线段树)

    传送门 解题思路 前两个操作都比较基础.对于第三个操作分类讨论一下,首先如果当前根不是要操作点的子树,那么就无影响,直接查询操作点的子树即可.第二种是当前根是操作点的子树,那就找到当前根到操作点这条链 ...

  3. 【树链剖分换根】P3979 遥远的国度

    Description zcwwzdjn在追杀十分sb的zhx,而zhx逃入了一个遥远的国度.当zcwwzdjn准备进入遥远的国度继续追杀时,守护神RapiD阻拦了zcwwzdjn的去路,他需要zcw ...

  4. BZOJ3083 遥远的国度 【树剖】

    题目 zcwwzdjn在追杀十分sb的zhx,而zhx逃入了一个遥远的国度.当zcwwzdjn准备进入遥远的国度继续追杀时,守护神RapiD阻拦了zcwwzdjn的去路,他需要zcwwzdjn完成任务 ...

  5. 【Luogu】P3979遥远的国度(树链剖分)

    题目链接 不会换根从暑假开始就困扰我了……拖到现在…… 会了还是很激动的. 换根操作事实上不需要(也不能)改树剖本来的dfs序……只是在query上动动手脚…… 设全树的集合为G,以root为根,u在 ...

  6. BZOJ 3083 遥远的国度(树链剖分+LCA)

    Description 描述zcwwzdjn在追杀十分sb的zhx,而zhx逃入了一个遥远的国度.当zcwwzdjn准备进入遥远的国度继续追杀时,守护神RapiD阻拦了zcwwzdjn的去路,他需要z ...

  7. 【luogu P3979 遥远的国度】 题解

    题目链接:https://www.luogu.org/problemnew/show/P3979 除了换根操作都是裸的树剖 所以换根时考虑: 1.我查询的根等于换的根:无影响 2.我查询的根是换的根的 ...

  8. 【BZOJ3083/3306】遥远的国度/树 树链剖分+线段树

    [BZOJ3083]遥远的国度 Description 描述zcwwzdjn在追杀十分sb的zhx,而zhx逃入了一个遥远的国度.当zcwwzdjn准备进入遥远的国度继续追杀时,守护神RapiD阻拦了 ...

  9. 【bzoj3083】遥远的国度 树链剖分+线段树

    题目描述 描述zcwwzdjn在追杀十分sb的zhx,而zhx逃入了一个遥远的国度.当zcwwzdjn准备进入遥远的国度继续追杀时,守护神RapiD阻拦了zcwwzdjn的去路,他需要zcwwzdjn ...

随机推荐

  1. C# 中类的成员有哪些?

    类(class)是C#类型中最基础的类型.类是一个数据结构,将状态(字段)和行为(方法和其他函数成员)组合在一个单元中.类提供了用于动态创建类实例的定义,也就是对象(object).类支持继承(inh ...

  2. OutOfRangeError的解决办法

    自制TFRecord数据集,训练神经网络出现的一个问题,及解决办法.   错误现象: 数据训练完成后,测试数据集正确率时,运行mnist_test.py文件,出现错误代码 问题分析:显示需测试数据10 ...

  3. centos禁止root用户ssh远程登录

    首先,我们要以root身份登录远程主机 vim指令编辑ssh配置文件,如 vim /etc/ssh/sshd_config 查找PermitRootLogin,把yes改为no 修改完配置需要重启ss ...

  4. 基于【 MySql 】一 || 主从复制

    一.centos7安装mysql 1. 先检查系统是否装有mysql rpm -qa | grep mysql 2. 下载mysql的repo源 wget http://repo.mysql.com/ ...

  5. ubuntu16.04 一键安装nginx-rtmp

    给nginx加rtmp协议,网上写的都是重新编译安装,这样会比较麻烦,编译的时候会报很多依赖缺失的问题,这个其实是可以通过apt-get一键安装 参考:https://blog.csdn.net/ka ...

  6. js写guess网页

    (一)布局           猜前                            ->                         猜后 (二)明确实现功能和具体实现: 1.网页生 ...

  7. 高射炮打蚊子,杀鸡用绝世好剑:在SAP Kyma上运行UI5应用

    国人在表述"大材小用"这个场景时,总喜欢用一些实物来类比,比如:高射炮打蚊子. 英国QF 3.7英寸(94mm)高射炮,战斗全重超过9.3吨,全长近5米,最大射程约18公里,最大射 ...

  8. Codeforces 853B Jury Meeting

    题意 从城市1-n来的评审团到城市0商讨国家大事,离开和抵达的那一天不能讨论,飞机均当天抵达,给出所有飞机起飞抵达代价情况,问能否使所有评审员聚齐连续k天并返回,并求最小代价 思路 从前向后扫一遍,求 ...

  9. 华擎 J3455 主板装 Linux 系统

    入手华擎J3455 ITX 主板,装备安装一个 redhat 来学习linux,及做一个家庭 web 服务器.但安装过程一波三折. 问题1.使用U盘引导不了,首先华擎这块板是 UEFI 板,用之前的老 ...

  10. Codeforces Round #590 (Div. 3) 万恶的自己WAC

    C题:一道简单的C题卡了半天,我太菜了 题意:给你一个n*2的矩阵,每个位置有一个数字,对应一种管道,要求通道可不可以从左上通到右下 由提议可以看出,1,2对应的是直管道,3,4,5,6对应弯管道,只 ...