bzoj 3083 树链剖分,换根

对于一颗树有以下操作

1.确定x为根,2.将u到v的简单路径上的数全改成c,3.询问当前以x为根的子树中的节点最小权值。

如果没有操作1:树链剖分很明显。

于是考虑换根对结果的影响:

Case 1:root=x 结果是全树最小值。

Case 2: root!=x且lca(root,x)=x 利用倍增求出x的孩子中是root祖先的那一个设为y,结果是全树除子树y以外最小值。

Case 3:lca(root,x)!=x 结果无影响,即子树x的最小值。

简述:树链剖分&lca/倍增

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int inf=;
  4. struct tr{int dep,sz,hs,tp,ls,rs,fa[];}t[];
  5. struct st{int mn,tg;}seg[];
  6. vector<int>g[];
  7. int n,m,ans,rt,tt,v[],ps[];
  8. void dfs1(int x,int p,int d)
  9. {
  10. t[x].fa[]=p;t[x].dep=d;t[x].hs=;t[x].sz=;
  11. for(int i=;i<=;i++)if(t[x].dep>=<<i)t[x].fa[i]=t[t[x].fa[i-]].fa[i-];
  12. for(int i=;i<g[x].size();i++)if(g[x][i]!=p)
  13. {
  14. dfs1(g[x][i],x,d+);
  15. if(t[t[x].hs].sz<t[g[x][i]].sz)t[x].hs=g[x][i];
  16. }
  17. }
  18. void dfs2(int x,int p)
  19. {
  20. t[x].tp=p;t[x].ls=ps[x]=++tt;
  21. if(t[x].hs)dfs2(t[x].hs,p);
  22. for(int i=;i<g[x].size();i++)if(g[x][i]!=t[x].fa[]&&g[x][i]!=t[x].hs)dfs2(g[x][i],g[x][i]);
  23. t[x].rs=tt;
  24. }
  25. void up(int x){seg[x].mn=min(seg[x<<].mn,seg[x<<|].mn);}
  26. void down(int x){seg[x<<]=seg[x<<|]=seg[x];seg[x].tg=;}
  27. void build(int x,int l,int r)
  28. {
  29. if(l==r){seg[x].mn=v[l];return;}
  30. int md=l+r>>;build(x<<,l,md);build(x<<|,md+,r);up(x);
  31. }
  32. void upd(int x,int l,int r,int tl,int tr,int c)
  33. {
  34. if(tl<=l&&r<=tr){seg[x]=(st){c,c};return;}
  35. if(seg[x].tg)down(x);
  36. int md=l+r>>;
  37. if(tl<=md)upd(x<<,l,md,tl,tr,c);
  38. if(tr>md)upd(x<<|,md+,r,tl,tr,c);
  39. up(x);
  40. }
  41. void qry(int x,int l,int r,int tl,int tr)
  42. {
  43. if(tl<=l&&r<=tr){ans=min(ans,seg[x].mn);return;}
  44. if(seg[x].tg)down(x);
  45. int md=l+r>>;
  46. if(tl<=md)qry(x<<,l,md,tl,tr);
  47. if(tr>md)qry(x<<|,md+,r,tl,tr);
  48. }
  49. int gtlca(int x,int y)
  50. {
  51. if(t[x].dep<t[y].dep)swap(x,y);
  52. int sub=t[x].dep-t[y].dep;
  53. for(int i=;i<=;i++)if(sub&(<<i))x=t[x].fa[i];
  54. for(int i=;i>=;i--)if(t[x].fa[i]!=t[y].fa[i])x=t[x].fa[i],y=t[y].fa[i];
  55. if(x==y)return x;else return t[x].fa[];
  56. }
  57. int gtanc(int x,int d){for(int i=;i<=;i++)if(d&(<<i))x=t[x].fa[i];return x;}
  58. void modify(int x,int y,int c)
  59. {
  60. int f1=t[x].tp,f2=t[y].tp;
  61. while(f1!=f2)
  62. {
  63. if(t[f1].dep<t[f2].dep){swap(f1,f2);swap(x,y);}
  64. upd(,,n,ps[f1],ps[x],c);
  65. x=t[f1].fa[];f1=t[x].tp;
  66. }
  67. if(t[x].dep>t[y].dep)swap(x,y);
  68. upd(,,n,ps[x],ps[y],c);
  69. }
  70. void query(int x)
  71. {
  72. int lca,v;
  73. lca=gtlca(rt,x);
  74. if(rt==x)printf("%d\n",seg[].mn);
  75. else
  76. {
  77. ans=inf;
  78. if(lca!=x)qry(,,n,t[x].ls,t[x].rs);
  79. else
  80. {
  81. v=gtanc(rt,t[rt].dep-t[x].dep-);
  82. if(t[v].ls>)qry(,,n,,t[v].ls-);
  83. if(t[v].rs<n)qry(,,n,t[v].rs+,n);
  84. }
  85. printf("%d\n",ans);
  86. }
  87. }
  88. int main()
  89. {
  90. scanf("%d%d",&n,&m);
  91. for(int i=;i<n;i++){int u,v;scanf("%d%d",&u,&v);g[u].push_back(v);g[v].push_back(u);}
  92. dfs1(,,);
  93. dfs2(,);
  94. for(int i=;i<=n;i++)scanf("%d",&v[ps[i]]);
  95. build(,,n);
  96. scanf("%d",&rt);
  97. for(int i=;i<=m;i++)
  98. {
  99. int kd,x,y,c;scanf("%d",&kd);
  100. if(kd==)scanf("%d",&rt);
  101. else if(kd==){scanf("%d%d%d",&x,&y,&c);modify(x,y,c);}
  102. else if(kd==){scanf("%d",&x);query(x);}
  103. }
  104. return ;
  105. }

bzoj 3083的更多相关文章

  1. BZOJ 3083 - 遥远的国度

    原题地址:http://www.lydsy.com/JudgeOnline/problem.php?id=3083 说话间又一个多月过去了..该来除除草了,每天都是训练.没效率,训练.没效率..省选考 ...

  2. BZOJ 3083: 遥远的国度 [树链剖分 DFS序 LCA]

    3083: 遥远的国度 Time Limit: 10 Sec  Memory Limit: 1280 MBSubmit: 3127  Solved: 795[Submit][Status][Discu ...

  3. BZOJ 3083: 遥远的国度 dfs序,树链剖分,倍增

    今天再做一天树的题目,明天要开始专攻图论了.做图论十几天之后再把字符串搞搞,区域赛前再把计几看看. 3083: 遥远的国度 Time Limit: 10 Sec  Memory Limit: 128 ...

  4. BZOJ 3083 遥远的国度 树链剖分

    3083: 遥远的国度 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 797  Solved: 181[Submit][Status] Descrip ...

  5. bzoj 3083 树链剖分

    首先我们先将树提出一个根变成有根树,那么我们可以通过树链剖分来实现对于子树的最小值求解,那么按照当前的根和询问的点的相对位置关系我们可以将询问变成某个子树和或者除去某颗子树之后其余的和,前者直接询问区 ...

  6. bzoj 3083 遥远的国度——树链剖分+线段树维护子树信息

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3083 int 的范围是 2^31 - 1 ,所以权值是不是爆 int 了…… O( nlog ...

  7. BZOJ 3083 遥远的国度(树链剖分+线段树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3083 [题目大意] 链修改,子树最小值查询和换根操作 [题解] 树链剖分练习题. [代 ...

  8. bzoj 3083 遥远的国度 —— 树链剖分

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3083 换根后路径还是不变,子树分类讨论一下,树剖后线段树维护即可. 代码如下: #inclu ...

  9. 【BZOJ 3083】遥远的国度

    这道题很简单的连剖+分类讨论,但是SDOI Round2要来了,不会手动栈怎么办呢?只好用一下这道题练习一下手动栈了,结果调了一天多QwQ 链剖的第一个dfs用bfs水过就行,但是我自以为是地把倍增写 ...

随机推荐

  1. Marathon自动扩缩容(marathon-lb-autoscale)

    我们在服务里面创建如下的应用(以下是创建完复制过来的json): { "id": "/nginxtest", "cmd": null, &q ...

  2. docker machine 使用教程

    之前,Docker的安装流程非常复杂,用户需要登录到相应的主机上,根据官方的安装和配置指南来安装Docker,并且不同的操作系统的安装步骤也是不一样的.而有了Machine后,不管是在笔记本.虚拟机还 ...

  3. [LeetCode] 490. The Maze_Medium tag: BFS/DFS

    There is a ball in a maze with empty spaces and walls. The ball can go through empty spaces by rolli ...

  4. vue的图片路径,和背景图片路径打包后错误解决

    最近在研究vue,老实的按照官网提供的,搭建的了 webpack+vue+vuex+vue-router,,因为是自己搭建的,所以踩了不少坑,一般问题百度都有,这个背景图片的问题,查了很久才解决. 1 ...

  5. 查看CPU信息

    基础知识 示例: 开发机器是1个物理CPU,4核8线程,Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz 基础 i3:2核模拟4线程,无睿频 i5:4核模拟4线程,有睿频 ...

  6. 用python.twisted.logfile每天记录日志,并用不记录stdout中的内容

    #导入的头 from twisted.python import logfrom twisted.python.logfile import * #开始记录,输入日志名和存放的路径,setStdout ...

  7. C++ 类定义

    C++ 类定义 定义一个类,本质上是定义一个数据类型的蓝图.这实际上并没有定义任何数据,但它定义了类的名称意味着什么,也就是说,它定义了类的对象包括了什么,以及可以在这个对象上执行哪些操作. 类定义是 ...

  8. SQLServer 里面的 DDL,DML,DCL,TCL(转)

    1.DDL (Data Definition Language )数据库定义语言 statements are used to define the database structure or sch ...

  9. 笔记 : 将本地项目上传到GitHub

    一.准备工作 1. 注册github账号https://github.com, 安装git工具 https://git-for-windows.github.io/ 2. 创建SSH KEY(由于本地 ...

  10. python文件基础IO,OS

    #!/usr/bin/python # -*- coding: UTF-8 -*- import os # 导入 Phone 包 #File 对象方法: file对象提供了操作文件的一系列方法. #O ...