Description

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

问题是这样的:遥远的国度有n个城市,这些城市之间由一些路连接且这些城市构成了一颗树。这个国度有一个首都,我们可以把这个首都看做整棵树的根,但遥远的国度比较奇怪,首都是随时有可能变为另外一个城市的。遥远的国度的每个城市有一个防御值,有些时候RapiD会使得某两个城市之间的路径上的所有城市的防御值都变为某个值。RapiD想知道在某个时候,如果把首都看做整棵树的根的话,那么以某个城市为根的子树的所有城市的防御值最小是多少。由于RapiD无法解决这个问题,所以他拦住了zcwwzdjn希望他能帮忙。但zcwwzdjn还要追杀sb的zhx,所以这个重大的问题就被转交到了你的手上。

Input

第1行两个整数n m,代表城市个数和操作数。
第2行至第n行,每行两个整数 u v,代表城市u和城市v之间有一条路。
第n+1行,有n个整数,代表所有点的初始防御值。
第n+2行一个整数 id,代表初始的首都为id。
第n+3行至第n+m+2行,首先有一个整数opt,如果opt=1,接下来有一个整数id,代表把首都修改为id;如果opt=2,接下来有三个整数p1 p2 v,代表将p1 p2路径上的所有城市的防御值修改为v;如果opt=3,接下来有一个整数 id,代表询问以城市id为根的子树中的最小防御值。

Output

对于每个opt=3的操作,输出一行代表对应子树的最小点权值。

Sample Input

3 7

1 2

1 3

1 2 3

1

3 1

2 1 1 6

3 1

2 2 2 5

3 1

2 3 3 4

3 1

Sample Output

1

2

3

4

提示

对于20%的数据,n<=1000 m<=1000。

对于另外10%的数据,n<=100000,m<=100000,保证修改为单点修改。

对于另外10%的数据,n<=100000,m<=100000,保证树为一条链。

对于另外10%的数据,n<=100000,m<=100000,没有修改首都的操作。

对于100%的数据,n<=100000,m<=100000,0<所有权值<=2^31。

题解:首先看到路径修改和子树查询,树链剖分就没得跑了,当然也可以写LCT

操作2/3用树剖自然好写,难的是一,换根怎么看怎么尬

想了一想,如果根就是询问点,子树就是整个区间

如果根在祖先,该点的子树不变.仍是按照正规的树剖查法查

如果根在询问点的任何一个子树中,那么该询问点的子树就变成了除了这个子树之外的所有区间.

主要是如何确定这个根在哪个子树中比较麻烦,写一个类似lca的玩意,倍增记录他的祖先,到时候一点点跳上去,复杂度还是可以接受的.

我一直以为是线段树写错了,果然做题太少了orz

代码如下:

  1. #include<cstdio>
  2. #include<vector>
  3. #include<cstring>
  4. #include<iostream>
  5. #include<algorithm>
  6. #define lson root<<1
  7. #define rson root<<1|1
  8. #define inf 0x3f3f3f3f
  9. using namespace std;
  10. struct node
  11. {
  12. int lazy,m,l,r;
  13. } tr[];
  14. int n,deep[],son[],fa[],size[],id[],top[],c[],w[],cnt,rt;
  15. vector<int> g[];
  16. void push_up(int root)
  17. {
  18. tr[root].m=min(tr[lson].m,tr[rson].m);
  19. }
  20. void push_down(int root)
  21. {
  22. tr[lson].m=tr[root].lazy;
  23. tr[lson].lazy=tr[root].lazy;
  24. tr[rson].m=tr[root].lazy;
  25. tr[rson].lazy=tr[root].lazy;
  26. tr[root].lazy=inf;
  27. }
  28. void build(int root,int l,int r)
  29. {
  30. if(l==r)
  31. {
  32. tr[root].l=l;
  33. tr[root].r=r;
  34. tr[root].lazy=inf;
  35. tr[root].m=w[l];
  36. return ;
  37. }
  38. int mid=(l+r)>>;
  39. tr[root].l=l;
  40. tr[root].r=r;
  41. tr[root].lazy=inf;
  42. build(lson,l,mid);
  43. build(rson,mid+,r);
  44. push_up(root);
  45. }
  46. void update(int root,int l,int r,int val)
  47. {
  48. if(l==tr[root].l&&r==tr[root].r)
  49. {
  50. tr[root].lazy=val;
  51. tr[root].m=val;
  52. return ;
  53. }
  54. int mid=(tr[root].l+tr[root].r)>>;
  55. if(tr[root].lazy!=inf)
  56. {
  57. push_down(root);
  58. }
  59. if(l>mid)
  60. {
  61. update(rson,l,r,val);
  62. }
  63. else
  64. {
  65. if(r<=mid)
  66. {
  67. update(lson,l,r,val);
  68. }
  69. else
  70. {
  71. update(lson,l,mid,val);
  72. update(rson,mid+,r,val);
  73. }
  74. }
  75. push_up(root);
  76. }
  77. int query(int root,int l,int r)
  78. {
  79. if(l>r)
  80. {
  81. return inf;
  82. }
  83. if(tr[root].l==l&&tr[root].r==r)
  84. {
  85. return tr[root].m;
  86. }
  87. int mid=(tr[root].l+tr[root].r)>>;
  88. if(tr[root].lazy!=inf)
  89. {
  90. push_down(root);
  91. }
  92. if(l>mid)
  93. {
  94. return query(rson,l,r);
  95. }
  96. else
  97. {
  98. if(r<=mid)
  99. {
  100. return query(lson,l,r);
  101. }
  102. }
  103. return min(query(lson,l,mid),query(rson,mid+,r));
  104. }
  105. void dfs1(int now,int f,int dep)
  106. {
  107. deep[now]=dep;
  108. fa[now]=f;
  109. size[now]=;
  110. int maxson=-;
  111. for(int i=; i<g[now].size(); i++)
  112. {
  113. if(g[now][i]==f)
  114. {
  115. continue;
  116. }
  117. dfs1(g[now][i],now,dep+);
  118. size[now]+=size[g[now][i]];
  119. if(size[g[now][i]]>maxson)
  120. {
  121. son[now]=g[now][i];
  122. maxson=size[g[now][i]];
  123. }
  124. }
  125. }
  126. void dfs2(int now,int topf)
  127. {
  128. id[now]=++cnt;
  129. w[cnt]=c[now];
  130. top[now]=topf;
  131. if(!son[now])
  132. {
  133. return ;
  134. }
  135. dfs2(son[now],topf);
  136. for(int i=; i<g[now].size(); i++)
  137. {
  138. if(g[now][i]==fa[now]||g[now][i]==son[now])
  139. {
  140. continue;
  141. }
  142. dfs2(g[now][i],g[now][i]);
  143. }
  144. }
  145. void path_update(int x,int y,int val)
  146. {
  147. while(top[x]!=top[y])
  148. {
  149. if(deep[top[x]]<deep[top[y]])
  150. {
  151. swap(x,y);
  152. }
  153. update(,id[top[x]],id[x],val);
  154. x=fa[top[x]];
  155. }
  156. if(deep[x]>deep[y])
  157. {
  158. swap(x,y);
  159. }
  160. update(,id[x],id[y],val);
  161. }
  162. int sub_query(int x)
  163. {
  164. if(x==rt)
  165. {
  166. return query(,,cnt);
  167. }
  168. if(id[rt]<=id[x]+size[x]-&&id[rt]>=id[x])
  169. {
  170. return min(query(,,id[x]-),query(,id[x]+size[x],cnt));
  171. }
  172. return query(,id[x],id[x]+size[x]-);
  173. }
  174. int main()
  175. {
  176. int n,m;
  177. scanf("%d%d",&n,&m);
  178. for(int i=;i<=n-;i++)
  179. {
  180. int from,to;
  181. scanf("%d%d",&from,&to);
  182. g[from].push_back(to);
  183. g[to].push_back(from);
  184. }
  185. for(int i=;i<=n;i++)
  186. {
  187. scanf("%d",&c[i]);
  188. }
  189. scanf("%d",&rt);
  190. dfs1(rt,,);
  191. dfs2(rt,rt);
  192. build(,,n);
  193. int kd,ll,rr,vv;
  194. for(int i=;i<=m;i++)
  195. {
  196. scanf("%d",&kd);
  197. if(kd==)
  198. {
  199. scanf("%d",&vv);
  200. rt=vv;
  201. }
  202. if(kd==)
  203. {
  204. scanf("%d%d%d",&ll,&rr,&vv);
  205. path_update(ll,rr,vv);
  206. }
  207. if(kd==)
  208. {
  209. scanf("%d",&vv);
  210. printf("%d\n",sub_query(vv));
  211. }
  212. }
  213. }

BZOJ 3083 遥远的国度(树链剖分+LCA)的更多相关文章

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

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

  2. BZOJ 3083: 遥远的国度(树链剖分+DFS序)

    可以很显而易见的看出,修改就是树链剖分,而询问就是在dfs出的线段树里查询最小值,但由于这道题会修改根节点,所以在查询的时候需判断x是否为root的祖先,如果不是就直接做,是的话应该查询从1-st[y ...

  3. BZOJ 3083 遥远的国度 树链剖分+线段树

    有换根的树链剖分的裸题. 在换根的时候注意讨论. 注意数据范围要开unsigned int或longlong #include<iostream> #include<cstdio&g ...

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

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

  5. BZOJ 3083 遥远的国度 树链剖分+脑子

    唉..又调了半天QWQ..为何读入挂了.....莫非读入是反着的????据ywy学长所言如是...OvO震惊 这啥骚题啊...还要换根...不过清明讲过...(然鹅我现在才做... 先随便选个点(比如 ...

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

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

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

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

  8. BZOJ 2243 染色 | 树链剖分模板题进阶版

    BZOJ 2243 染色 | 树链剖分模板题进阶版 这道题呢~就是个带区间修改的树链剖分~ 如何区间修改?跟树链剖分的区间询问一个道理,再加上线段树的区间修改就好了. 这道题要注意的是,无论是线段树上 ...

  9. 【BZOJ】2819: Nim(树链剖分 / lca+dfs序+树状数组)

    题目 传送门:QWQ 分析 先敲了个树链剖分,发现无法AC(其实是自己弱,懒得debug.手写栈) 然后去学了学正解 核心挺好理解的,$ query(a) $是$ a $到根的异或和. 答案就是$ l ...

随机推荐

  1. Java 引用类型数组

    引用类型变量可以使用类.接口或数组来声明. 数组引用变量是存放在栈内存(stack)中,数组元素是存放在堆内存(heap)中,通过栈内存中的指针指向对应元素在堆内存中的位置来实现访问. public ...

  2. 如何在已经安装好的Nginx上增加新模块

    学习资源: https://blog.csdn.net/dxm2025/article/details/41149865 https://blog.csdn.net/qq_36663951/artic ...

  3. gitlab的本地搭建和部署使用

    公司现在的代码管理是在公司的服务器上部署了gitlab,这样既方便协同开发,有可以很好的保护代码的安全性. 那么我们就来研究一下 如何给自己的服务器上部署gitlab吧! 学习源头:https://w ...

  4. Jenkins设置自动发邮件

    安装Jenkins方法详解:https://www.cnblogs.com/lizhe860/p/9901257.html 一.设置全局变量 从首页依次进入系统工具→系统设置 二.在项目配置中设置项目 ...

  5. python学习(十七) 扩展python

    c, c++, java比python快几个数量级. 17.1 考虑哪个更重要 开发速度还是运行速度更重要. 17.2 非常简单的途径:Jython和IronPython Jython可以直接访问JA ...

  6. [原创]Java使用反射及自定义注解实现对象差异性比较

    Java项目C中 有一处逻辑,对于资源数据(类型为ResourceItem,拥有int/double/boolean/String类型数十个字段),需要比对资源数据每次变更的差异,并描述出变更情况.并 ...

  7. Android Studio 配置模拟器AVD存放路径(默认在c盘,解决c盘空间不够问题)

    Android Studio 安装之后,默认的会给我们创建一个 Nexus 的模拟器, 这个模拟器的镜像文件放在了 C:\Users\Administrator\.android  中 其中的avd文 ...

  8. [JBPM3.2]TaskNode的signal属性详解

    TaskNode节点的signal属性决定了任务完成时对流程执行继续的影响,共有六种取值:unsynchronized,never,first,first-wait,last,last-wait.默认 ...

  9. Scala语言简介和开发环境配置

    Scala语言的简介和开发环境搭建 Scala是一门结合了面向对象特征和函数式编程特征的语言,它是一个创新的编程语言产品.Scala可以做脚本(就像shell脚本一样),可以做服务端编程语言,可以写数 ...

  10. go语言 robfig/cron包 实现定时 调用

    package main import ( "github.com/robfig/cron" "time" "fmt" "os&q ...