原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ30.html

题目传送门 - UOJ#30

题意

  uoj写的很简洁、清晰,这里就不抄一遍了。

题解

  首先建出圆方树。接下来,我们称"圆点"为原来有的点,"方点"为新增的点。

  然后先只考虑在线询问如何做。

    ——把方点的值设置成所有与他连边的圆点的权值的最小值,直接在圆方树上树链剖分再套个线段树支持一下区间询问即可。

  然后会发现这样做支持不了修改操作。

    ——直接来个菊花图不断修改根节点就GG了。

  于是我们考虑进一步想办法。

  我们把方点的值重新定义成“在圆方树上,该点的儿子的权值的最小值”。那么,在询问的时候,其他都一样,但是如果 lca 为方点,那么加上其 fa 对 min 的贡献即可。

  时间复杂度 $O(n\log ^2 n )$ 。

代码

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long LL;
  4. LL read(){
  5. LL x=0,f=1;
  6. char ch=getchar();
  7. while (!isdigit(ch)&&ch!='-')
  8. ch=getchar();
  9. if (ch=='-')
  10. f=-1,ch=getchar();
  11. while (isdigit(ch))
  12. x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
  13. return x*f;
  14. }
  15. const int N=200005,INF=1.1e9;
  16. int pr[N],dfn[N],low[N],st[N],Time,top,tot;
  17. multiset <int> Mins[N];
  18. vector <int> G[N],g[N];
  19. void Tarjan(int x){
  20. low[x]=dfn[x]=++Time,st[++top]=x;
  21. for (auto y : G[x])
  22. if (!dfn[y]){
  23. Tarjan(y);
  24. low[x]=min(low[x],low[y]);
  25. if (low[y]>=dfn[x]){
  26. tot++;
  27. g[x].push_back(tot);
  28. g[tot].push_back(x);
  29. int z;
  30. do {
  31. z=st[top--];
  32. g[z].push_back(tot);
  33. g[tot].push_back(z);
  34. } while (z!=y);
  35. }
  36. }
  37. else
  38. low[x]=min(low[x],dfn[y]);
  39. }
  40. namespace sp{
  41. int n,outn;
  42. int fa[N],son[N],size[N],depth[N],top[N],p[N],ap[N],cnp=0,val[N];
  43. void dfs(int x,int pre,int d){
  44. size[x]=1,fa[x]=pre,son[x]=-1,depth[x]=d;
  45. for (auto y : g[x])
  46. if (y!=pre){
  47. dfs(y,x,d+1);
  48. size[x]+=size[y];
  49. if (son[x]==-1||size[y]>size[son[x]])
  50. son[x]=y;
  51. }
  52. }
  53. void Get_Top(int x,int tp){
  54. top[x]=tp;
  55. ap[p[x]=++cnp]=x;
  56. if (son[x]==-1)
  57. return;
  58. Get_Top(son[x],tp);
  59. for (auto y : g[x])
  60. if (y!=fa[x]&&y!=son[x])
  61. Get_Top(y,y);
  62. }
  63. int Min[N<<2];
  64. void build(int rt,int L,int R){
  65. if (L==R)
  66. return (void)(Min[rt]=val[ap[L]]);
  67. int mid=(L+R)>>1,ls=rt<<1,rs=ls|1;
  68. build(ls,L,mid);
  69. build(rs,mid+1,R);
  70. Min[rt]=min(Min[ls],Min[rs]);
  71. }
  72. int query(int rt,int L,int R,int xL,int xR){
  73. if (xL>xR||L>xR||R<xL)
  74. return INF;
  75. if (xL<=L&&R<=xR)
  76. return Min[rt];
  77. int mid=(L+R)>>1,ls=rt<<1,rs=ls|1;
  78. return min(query(ls,L,mid,xL,xR),query(rs,mid+1,R,xL,xR));
  79. }
  80. void update(int rt,int L,int R,int x,int d){
  81. if (L==R)
  82. return (void)(Min[rt]=d);
  83. int mid=(L+R)>>1,ls=rt<<1,rs=ls|1;
  84. if (x<=mid)
  85. update(ls,L,mid,x,d);
  86. else
  87. update(rs,mid+1,R,x,d);
  88. Min[rt]=min(Min[ls],Min[rs]);
  89. }
  90. int query(int a,int b){
  91. int f1=top[a],f2=top[b],ans=INF;
  92. while (f1!=f2){
  93. if (depth[f1]<depth[f2])
  94. swap(f1,f2),swap(a,b);
  95. ans=min(ans,query(1,1,n,p[f1],p[a]));
  96. a=fa[f1],f1=top[a];
  97. }
  98. if (depth[a]>depth[b])
  99. swap(a,b);
  100. if (a>outn&&fa[a]!=0)
  101. ans=min(ans,query(1,1,n,p[fa[a]],p[fa[a]]));
  102. return min(ans,query(1,1,n,p[a],p[b]));
  103. }
  104. }
  105. int main(){
  106. int n=tot=read(),m=read(),q=read();
  107. for (int i=1;i<=n;i++)
  108. pr[i]=read();
  109. for (int i=1;i<=m;i++){
  110. int a=read(),b=read();
  111. G[a].push_back(b);
  112. G[b].push_back(a);
  113. }
  114. Tarjan(1);
  115. sp :: dfs(1,0,0);
  116. sp :: Get_Top(1,1);
  117. for (int i=n+1;i<=tot;i++)
  118. Mins[i].insert(INF);
  119. for (int i=1;i<=n;i++)
  120. Mins[sp :: fa[i]].insert(pr[i]);
  121. for (int i=1;i<=n;i++)
  122. sp :: val[i]=pr[i];
  123. for (int i=n+1;i<=tot;i++)
  124. sp :: val[i]=*Mins[i].begin();
  125. sp :: build(1,1,sp :: n=tot);
  126. sp :: outn=n;
  127. while (q--){
  128. char s[10];
  129. scanf("%s",s);
  130. int x=read(),y=read();
  131. if (s[0]=='A')
  132. printf("%d\n",sp :: query(x,y));
  133. else {
  134. int f=sp :: fa[x];
  135. if (f){
  136. Mins[f].erase(Mins[f].find(pr[x]));
  137. Mins[f].insert(pr[x]=y);
  138. sp :: update(1,1,sp :: n,sp :: p[f],*Mins[f].begin());
  139. }
  140. sp :: update(1,1,sp :: n,sp :: p[x],y);
  141. }
  142. }
  143. return 0;
  144. }

  

UOJ#30/Codeforces 487E Tourists 点双连通分量,Tarjan,圆方树,树链剖分,线段树的更多相关文章

  1. HDU 2460 Network(双连通+树链剖分+线段树)

    HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...

  2. Water Tree CodeForces 343D 树链剖分+线段树

    Water Tree CodeForces 343D 树链剖分+线段树 题意 给定一棵n个n-1条边的树,起初所有节点权值为0. 然后m个操作, 1 x:把x为根的子树的点的权值修改为1: 2 x:把 ...

  3. Educational Codeforces Round 3 E. Minimum spanning tree for each edge 最小生成树+树链剖分+线段树

    E. Minimum spanning tree for each edge time limit per test 2 seconds memory limit per test 256 megab ...

  4. Codeforces Round #200 (Div. 1) D. Water Tree 树链剖分+线段树

    D. Water Tree time limit per test 4 seconds memory limit per test 256 megabytes input standard input ...

  5. Codeforces 487E Tourists [广义圆方树,树链剖分,线段树]

    洛谷 Codeforces 思路 首先要莫名其妙地想到圆方树. 建起圆方树后,令方点的权值是双联通分量中的最小值,那么\((u,v)\)的答案就是路径\((u,v)\)上的最小值. 然而这题还有修改, ...

  6. CF487 E. Tourists [点双连通分量 树链剖分 割点]

    E. Tourists 题意: 无向连通图 C a w: 表示 a 城市的纪念品售价变成 w. A a b: 表示有一个游客要从 a 城市到 b 城市,你要回答在所有他的旅行路径中最低售价的最低可能值 ...

  7. Simple Cycles Edges CodeForces - 962F(点双连通分量)

    题意: 求出简单环的所有边,简单环即为边在一个环内 解析: 求出点双连通分量,如果一个连通分量的点数和边数相等,则为一个简单环 点双连通分量  任意两个点都至少存在两条点不重复的路径  即任意两条边都 ...

  8. codeforces 487E Tourists

    如果不是uoj上有的话(听说这是China Round),我有可能就错过这道题目了(这是我有史以来为oi写的最长的代码,用了我一天TAT!). 题目 传送门. 一个连通无向图,点上有权,支持两种操作: ...

  9. 点/边 双连通分量---Tarjan算法

    运用Tarjan算法,求解图的点/边双连通分量. 1.点双连通分量[块] 割点可以存在多个块中,每个块包含当前节点u,分量以边的形式输出比较有意义. typedef struct{ //栈结点结构 保 ...

随机推荐

  1. Affiliate实战记录之一:CPI、CPA、CPM...名词解释

    1.CPM (Cost Per Mille,或者Cost Per Thousand;Cost Per Impressions) 每千人成本,按展示次数收费 网上广告收费最科学的办法是按照有多少人看到你 ...

  2. Oracle Ora 错误解决方案合集

    注:本文来源于 < Oracle学习笔记 --- Oracle ORA错误解决方案 > ORA-00001: 违反唯一约束条件 (.)错误说明:当在唯一索引所对应的列上键入重复值时,会触发 ...

  3. Confluence 6 XML 备份恢复失败的问题解决

    XML 站点备份仅仅针对新数据库恢复的时候是必要的. Upgrading Confluence,Setting up a test server 或者 Production Backup Strate ...

  4. Confluence 6 升级自定义的站点和空间获得你的自定义布局

    我们建议你在对站点进行布局修改的时候,你需要为你修改的 Confluence 站点或空间布局保留所有的修改记录. 如果没有的话,你应该可以通过下面的办法找到你的自定义修改.这个方法将会把你对全部网站和 ...

  5. 【深度学习】吴恩达网易公开课练习(class1 week3)

    知识点梳理 python工具使用: sklearn: 数据挖掘,数据分析工具,内置logistic回归 matplotlib: 做图工具,可绘制等高线等 绘制散点图: plt.scatter(X[0, ...

  6. Nginx详解五:Nginx基础篇之HTTP请求

    http请求 如今的http请求已经不是每一次请求都进行一次三次握手,可以在请求与相应之后,客户端和服务端不断的发送FIN和ACK包来保持连接的状态,即:长连接 HTTP请求建立在一次TCP连接基础上 ...

  7. Yslow web性能测试插件

    YSlow可以对网站的页面进行分析,并告诉你为了提高网站性能,如何基于某些规则而进行优化. YSlow可以分析任何网站,并为每一个规则产生一个整体报告,如果页面可以进行优化,则YSlow会列出具体的修 ...

  8. 步步为营-87-imageAreaSelect插件使用(图片剪切)

    1 引用文件 jquery.imgareaselect.min.cs imgareaselect-default.js 2 代码 <%@ Page Language="C#" ...

  9. mysql的innodb存储引擎

    innodb是支持事务的存储引擎,支持ACID特性的ACID(指数据库事务正确执行的四个基本要素的缩写) 包含:原子性(Atomicity).一致性(Consistency).隔离性(Isolatio ...

  10. javascript 面向对象-面试题实例

    / 从设计到模式 // 设计模式简介 // 设计 // 模式 // 分开 // 从设计到模式 // 23种设计模式 // 创建型 // 工厂模式(工厂方法模式,抽象工厂模式,建造者模式) // 单例模 ...