本题解并不提供圆方树讲解。

所以不会圆方树的出门右转问yyb

没有修改的话圆方树+链剖。

方点的权值为点双连通分量里的最小值。

然后修改的话圆点照修,每一个方点维护一个小根堆。

考虑到可能被菊花卡死。

我们每一个方点只维护儿子的最小值。

当询问的路径\(lca\)为方点时,\(ans=min(ans,w[fa[lca]])\)即可。

  1. #include<iostream>
  2. #include<cstring>
  3. #include<cstdio>
  4. #include<cmath>
  5. #include<algorithm>
  6. #include<queue>
  7. using namespace std;
  8. #define ls now<<1
  9. #define rs now<<1|1
  10. const int N=444444;
  11. struct queue{
  12. priority_queue<int,vector<int>,greater<int> >q1;
  13. priority_queue<int,vector<int>,greater<int> >q2;
  14. void push(int x){q1.push(x);}
  15. void del(int x){q2.push(x);}
  16. int top(){
  17. while(!q2.empty()&&q1.top()==q2.top())q1.pop(),q2.pop();
  18. return q1.top();
  19. }
  20. }q[N];
  21. struct Graph{
  22. int cnt,head[N];
  23. struct edge{
  24. int to,nxt;
  25. }e[N*2];
  26. void add_edge(int u,int v){
  27. cnt++;
  28. e[cnt].nxt=head[u];
  29. e[cnt].to=v;
  30. head[u]=cnt;
  31. }
  32. }g1,g2;
  33. int dfn[N],low[N],tim,stack[N],Top,num;
  34. void Tarjan(int u){
  35. dfn[u]=low[u]=++tim;
  36. stack[++Top]=u;
  37. for(int i=g1.head[u];i;i=g1.e[i].nxt){
  38. int v=g1.e[i].to;
  39. if(dfn[v]==0){
  40. Tarjan(v);
  41. low[u]=min(low[v],low[u]);
  42. if(low[v]>=dfn[u]){
  43. g2.add_edge(++num,u);
  44. g2.add_edge(u,num);
  45. int x;
  46. do{
  47. x=stack[Top--];
  48. g2.add_edge(num,x);
  49. g2.add_edge(x,num);
  50. }while(x!=v);
  51. }
  52. }
  53. else low[u]=min(low[u],dfn[v]);
  54. }
  55. }
  56. int fa[N],size[N],dep[N],son[N];
  57. int n,w[N];
  58. void dfs1(int u,int f){
  59. fa[u]=f;
  60. size[u]=1;
  61. dep[u]=dep[f]+1;
  62. for(int i=g2.head[u];i;i=g2.e[i].nxt){
  63. int v=g2.e[i].to;
  64. if(v==f)continue;
  65. if(u>n)q[u].push(w[v]);
  66. dfs1(v,u);
  67. size[u]+=size[v];
  68. if(size[son[u]]<=size[v])son[u]=v;
  69. }
  70. }
  71. int top[N],id[N],tot;
  72. void dfs2(int u,int tp){
  73. dfn[u]=++tot;
  74. top[u]=tp;
  75. id[tot]=u;
  76. if(son[u])dfs2(son[u],tp);
  77. for(int i=g2.head[u];i;i=g2.e[i].nxt){
  78. int v=g2.e[i].to;
  79. if(v==fa[u]||v==son[u])continue;
  80. dfs2(v,v);
  81. }
  82. }
  83. int mn[N*4];
  84. void update(int now){
  85. mn[now]=min(mn[ls],mn[rs]);
  86. }
  87. void build(int l,int r,int now){
  88. if(l==r){
  89. if(id[l]<=n)mn[now]=w[id[l]];
  90. else mn[now]=q[id[l]].top();
  91. return;
  92. }
  93. int mid=(l+r)>>1;
  94. build(l,mid,ls);
  95. build(mid+1,r,rs);
  96. update(now);
  97. }
  98. void change(int l,int r,int x,int c,int now){
  99. if(l==r){
  100. mn[now]=c;
  101. return;
  102. }
  103. int mid=(l+r)>>1;
  104. if(x>mid)change(mid+1,r,x,c,rs);
  105. else change(l,mid,x,c,ls);
  106. update(now);
  107. }
  108. int check(int l,int r,int L,int R,int now){
  109. if(l==L&&r==R)return mn[now];
  110. int mid=(l+r)>>1;
  111. if(L>mid)return check(mid+1,r,L,R,rs);
  112. else if(R<=mid)return check(l,mid,L,R,ls);
  113. else return min(check(l,mid,L,mid,ls),check(mid+1,r,mid+1,R,rs));
  114. }
  115. int getlca(int x,int y){
  116. while(top[x]!=top[y]){
  117. if(dep[top[x]]<dep[top[y]])swap(x,y);
  118. x=fa[top[x]];
  119. }
  120. if(dep[x]<dep[y])return x;
  121. else return y;
  122. }
  123. int checkroad(int x,int y){
  124. int mn=-1;
  125. while(top[x]!=top[y]){
  126. if(dep[top[x]]<dep[top[y]])swap(x,y);
  127. if(mn==-1)mn=check(1,num,dfn[top[x]],dfn[x],1);
  128. else mn=min(mn,check(1,num,dfn[top[x]],dfn[x],1));
  129. x=fa[top[x]];
  130. }
  131. if(dep[x]>dep[y])swap(x,y);
  132. if(mn==-1)mn=check(1,num,dfn[x],dfn[y],1);
  133. else mn=min(mn,check(1,num,dfn[x],dfn[y],1));
  134. return mn;
  135. }
  136. int read(){
  137. int sum=0,f=1;char ch=getchar();
  138. while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
  139. while(ch>='0'&&ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
  140. return sum*f;
  141. }
  142. int Q,m;
  143. int main(){
  144. n=read();m=read();Q=read();
  145. num=n;
  146. for(int i=1;i<=n;i++)w[i]=read();
  147. for(int i=1;i<=m;i++){
  148. int u=read(),v=read();
  149. g1.add_edge(u,v);g1.add_edge(v,u);
  150. }
  151. Tarjan(1);
  152. dfs1(1,0);
  153. dfs2(1,1);
  154. build(1,num,1);
  155. char s[3];
  156. while(Q--){
  157. scanf("%s",s+1);
  158. if(s[1]=='C'){
  159. int x=read(),c=read();
  160. if(dfn[x]!=1){
  161. q[fa[x]].del(w[x]);
  162. q[fa[x]].push(c);
  163. change(1,num,dfn[fa[x]],q[fa[x]].top(),1);
  164. }
  165. w[x]=c;
  166. change(1,num,dfn[x],c,1);
  167. }
  168. else{
  169. int x=read(),y=read();
  170. int lca=getlca(x,y);
  171. int tmp=checkroad(x,y);
  172. printf("%d\n",lca<=n?tmp:min(tmp,w[fa[lca]]));
  173. }
  174. }
  175. return 0;
  176. }

CF487E Tourists(圆方树+堆+链剖)的更多相关文章

  1. CF487E Tourists(圆方树+树链剖分+multiset/可删堆)

    CF487E Tourists(圆方树+树链剖分+multiset/可删堆) Luogu 给出一个带点权的无向图,两种操作: 1.修改某点点权. 2.询问x到y之间简单路径能走过的点的最小点权. 题解 ...

  2. CF487E Tourists 圆方树、树链剖分

    传送门 注意到我们需要求的是两点之间所有简单路径中最小值的最小值,那么对于一个点双联通分量来说,如果要经过它,则一定会经过这个点双联通分量里权值最小的点 注意:这里不能缩边双联通分量,样例\(2\)就 ...

  3. CF487E Tourists + 圆方树学习笔记(圆方树+树剖+线段树+multiset)

    QWQ果然我已经什么都学不会的人了. 这个题目要求的是图上所有路径的点权和!QWQ(我只会树上啊!) 这个如果是好啊 这时候就需要 圆方树! 首先在介绍圆方树之前,我们先来一点简单的前置知识 首先,我 ...

  4. CF487E Tourists[圆方树+树剖(线段树套set)]

    做这题的时候有点怂..基本已经想到正解了..结果感觉做法有点假,还是看了正解题解.. 首先提到简单路径上经过的点,就想到了一个关于点双的结论:两点间简单路径上所有可能经过的点的并等于路径上所有点所在点 ...

  5. uoj30【CF Round #278】Tourists(圆方树+树链剖分+可删除堆)

    - 学习了一波圆方树 学习了一波点分治 学习了一波可删除堆(巧用 ? STL) 传送门: Icefox_zhx 注意看代码看怎么构建圆方树的. tips:tips:tips:圆方树内存记得开两倍 CO ...

  6. Tourists——圆方树

    CF487E Tourists 一般图,带修求所有简单路径代价. 简单路径,不能经过同一个点两次,那么每个V-DCC出去就不能再回来了. 所以可以圆方树,然后方点维护一下V-DCC内的最小值. 那么, ...

  7. CF487E Tourists 【圆方树 + 树剖 + 堆】

    题目链接 CF487E 题解 圆方树 + 树剖 裸题 建好圆方树维护路径上最小值即可 方点的值为其儿子的最小值,这个用堆维护 为什么只维护儿子?因为这样修改点的时候就只需要修改其父亲的堆 这样充分利用 ...

  8. UOJ#30/Codeforces 487E Tourists 点双连通分量,Tarjan,圆方树,树链剖分,线段树

    原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ30.html 题目传送门 - UOJ#30 题意 uoj写的很简洁.清晰,这里就不抄一遍了. 题解 首先建 ...

  9. CF487E Tourists【圆方树+tarjan+multiset+树剖+线段树】

    圆方树不仅能解决仙人掌问题(虽然我仙人掌问题也没用过圆方树都是瞎搞过去的),还可以解决一般图的问题 一般图问题在于缩完环不是一棵树,所以就缩点双(包括双向边) 每个方点存他所在点双内除根以外的点的最小 ...

随机推荐

  1. WEBGL学习【十五】利用WEBGL实现三维场景的一般思路总结

    实现三维场景载入操作的实现步骤: 主要知识点:着色器,纹理贴图,文件载入 实现思路: 获取canvas,初始化WEBGL上下文信息. 主要是实现WEBGL上下文的获取,设置视的大小,此时gl存储了WE ...

  2. javascript 富文本 注意事项

    富文本编辑器 div内嵌iframe iframe body contenteditable属性 true 整个iframe 即为可编辑框,创建时注意事项: 1.编辑 焦点问题 弹出新控件时为控件设置 ...

  3. Project Euler 42 Coded triangle numbers

    题意:三角形数序列的第n项由公式tn = 1/2n(n+1)给出:因此前十个三角形数是: 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, - 将一个单词的每个字母分别转化为其 ...

  4. HDU2516 - 取石子游戏【斐波那契博弈】

    基本描述 有一堆个数为n的石子,游戏双方轮流取石子,满足: 先手不能再第一次把所有石子取完: 之后每次可以取的石子数介于1到对手刚取的石子数的2倍之间,包括1和对手取的石子数的2倍.  取最后石子的人 ...

  5. LVS的使用

    lvs: Linux Virtual Server l4:四层交换:四层路由: 根据请求报文的目标IP和PORT将其转发至后端主机集群中的某一台主机(根据挑选算法): netfilter: PRERO ...

  6. Django入门--模板路径配置及渲染

    模板就是前端的页面,Django把html源码写到模板文件中,然后通过特定方法渲染后交给客户端. 模板路径设置方法有两种,分别是在项目目录下设置以及在应用目录下设置. 模板查找顺序:优先在DIRS设置 ...

  7. webKit 内核浏览器 源码分析

    如需转载,请注明出处! WebSite: http://www.jjos.org/ 作者: 姜江 linuxemacs@gmail.com QQ: 457283 这是一篇自己写于一年前的工作文档,分享 ...

  8. VS2015 C#取消最大化按钮,设置鼠标不可调整窗体大小

    取消最大化按钮设置  设置窗体不可被鼠标调整大小

  9. “王者对战”之 MySQL 8 vs PostgreSQL 10

    既然 MySQL 8 和 PostgreSQL 10 已经发布了,现在是时候回顾一下这两大开源关系型数据库是如何彼此竞争的. 在这些版本之前,人们普遍认为,Postgres 在功能集表现更出色,也因其 ...

  10. unity3d 中动画的帧事件

    代码事件监听 using UnityEngine; using System.Collections; public class BoxEventScript : MonoBehaviour { vo ...