线段树每个结点维护5个域:

整个区间的MST。

将两个左端点连通,两个右端点不连通,整个区间内选择2*(r-l+1)-2条边的最小生成森林,有两个连通块。

将两个右端点连通,两个左端点不连通,整个区间内选择2*(r-l+1)-2条边的最小生成森林,有两个连通块。

两个左端点不连通,两个右端点也不连通,整个区间内选择2*(r-l+1)-2条边的最小生成森林,有两个连通块。(就是上面一条线,下面一条线)

两个左端点不连通,两个右端点也不连通,整个区间内选择2*(r-l+1)-3条边的最小生成森林,有3个连通块。

合并时讨论5*5*2(两条夹缝里的横边是否都选择)种情况。

  1. /*每个结点维护5个域:左右完全连通,左连通右不连通,右连通左不连通,左右都不连通2,左右都不连通3*/
  2. #include<cstdio>
  3. #include<algorithm>
  4. using namespace std;
  5. #define N 60001
  6. #define INF 1000000000
  7. int n,m,heng[2][N],zong[N];
  8. struct Node
  9. {
  10. int z1y1,z1y0,z0y1,z0y02,z0y03;
  11. void reset(){z1y1=z1y0=z0y1=z0y02=z0y03=INF;}
  12. }T[N<<2];
  13. inline void pushup(Node &rt,const Node &ls,const Node &rs,const int &r1,const int &l1,const int &l2)
  14. {
  15. rt.reset();
  16.  
  17. int MIN=min(heng[0][r1],heng[1][r1]),SUM=heng[0][r1]+heng[1][r1];
  18.  
  19. /*z1y1+z1y1*/rt.z1y1=ls.z1y1+rs.z1y1+MIN;
  20. if(l2>1)/*z1y1+z1y0*/rt.z1y0=ls.z1y1+rs.z1y0+MIN;
  21. if(l2>1)/*z1y1+z0y1*/rt.z1y1=min(rt.z1y1,ls.z1y1+rs.z0y1+SUM);
  22. /*z1y1+z0y02*/rt.z1y1=min(rt.z1y1,ls.z1y1+rs.z0y02+SUM);
  23. rt.z1y0=min(rt.z1y0,ls.z1y1+rs.z0y02+MIN);
  24. if(l2>1)/*z1y1+z0y03*/rt.z1y0=min(rt.z1y0,ls.z1y1+rs.z0y03+SUM);
  25.  
  26. if(l1>1)/*z1y0+z1y1*/rt.z1y1=min(rt.z1y1,ls.z1y0+rs.z1y1+SUM);
  27. if(l1>1&&l2>1)/*z1y0+z1y0*/rt.z1y0=min(rt.z1y0,ls.z1y0+rs.z1y0+SUM);
  28. /*z1y0+z0y1不合法*/
  29. if(l1>1)/*z1y0+z0y02*/rt.z1y0=min(rt.z1y0,ls.z1y0+rs.z0y02+SUM);
  30. /*z1y0+z0y03不合法*/
  31.  
  32. if(l1>1)/*z0y1+z1y1*/rt.z0y1=ls.z0y1+rs.z1y1+MIN;
  33. if(l1>1&&l2>1)/*z0y1+z1y0*/rt.z0y03=ls.z0y1+rs.z1y0+MIN;
  34. if(l1>1&&l2>1)/*z0y1+z0y1*/rt.z0y1=min(rt.z0y1,ls.z0y1+rs.z0y1+SUM);
  35. if(l1>1)/*z0y1+z0y02*/rt.z0y1=min(rt.z0y1,ls.z0y1+rs.z0y02+SUM),
  36. rt.z0y03=min(rt.z0y03,ls.z0y1+rs.z0y02+MIN);
  37. if(l1>1&&l2>1)/*z0y1+z0y03*/rt.z0y03=min(rt.z0y03,ls.z0y1+rs.z0y03+SUM);
  38.  
  39. /*z0y02+z1y1*/rt.z1y1=min(rt.z1y1,ls.z0y02+rs.z1y1+SUM);
  40. rt.z0y1=min(rt.z0y1,ls.z0y02+rs.z1y1+MIN);
  41. if(l2>1)/*z0y02+z1y0*/rt.z1y0=min(rt.z1y0,ls.z0y02+rs.z1y0+SUM),
  42. rt.z0y03=min(rt.z0y03,ls.z0y02+rs.z1y0+MIN);
  43. if(l2>1)/*z0y02+z0y1*/rt.z0y1=min(rt.z0y1,ls.z0y02+rs.z0y1+SUM);
  44. /*z0y02+z0y02*/rt.z0y02=ls.z0y02+rs.z0y02+SUM;
  45. rt.z0y03=min(rt.z0y03,ls.z0y02+rs.z0y02+MIN);
  46. if(l2>1)/*z0y02+z0y03*/rt.z0y03=min(rt.z0y03,ls.z0y02+rs.z0y03+SUM);
  47.  
  48. if(l1>1)/*z0y03+z1y1*/rt.z0y1=min(rt.z0y1,ls.z0y03+rs.z1y1+SUM);
  49. if(l1>1&&l2>1)/*z0y03+z1y0*/rt.z0y03=min(rt.z0y03,ls.z0y03+rs.z1y0+SUM);
  50. /*z0y03+z0y1不合法*/
  51. if(l1>1)/*z0y03+z0y02*/rt.z0y03=min(rt.z0y03,ls.z0y03+rs.z0y02+SUM);
  52. /*z0y03+z0y03不合法*/
  53. }
  54. void buildtree(int rt,int l,int r)
  55. {
  56. if(l==r)
  57. {
  58. T[rt].z1y1=zong[l];
  59. return;
  60. }
  61. int m=(l+r>>1);
  62. buildtree(rt<<1,l,m);
  63. buildtree(rt<<1|1,m+1,r);
  64. pushup(T[rt],T[rt<<1],T[rt<<1|1],m,m-l+1,r-m);
  65. }
  66. void update(int p,int v,int rt,int l,int r)
  67. {
  68. if(l==r)
  69. {
  70. zong[p]=v;
  71. T[rt].z1y1=v;
  72. return;
  73. }
  74. int m=(l+r>>1);
  75. if(p<=m) update(p,v,rt<<1,l,m);
  76. else update(p,v,rt<<1|1,m+1,r);
  77. pushup(T[rt],T[rt<<1],T[rt<<1|1],m,m-l+1,r-m);
  78. }
  79. void update(int p,int rt,int l,int r)
  80. {
  81. if(l==r) return;
  82. int m=(l+r>>1);
  83. if(p<=m) update(p,rt<<1,l,m);
  84. else update(p,rt<<1|1,m+1,r);
  85. pushup(T[rt],T[rt<<1],T[rt<<1|1],m,m-l+1,r-m);
  86. }
  87. Node query(int ql,int qr,int rt,int l,int r)
  88. {
  89. if(ql<=l && r<=qr) return T[rt];
  90. int m=(l+r>>1);
  91. if(ql<=m && m<qr)
  92. {
  93. Node res;
  94. pushup(res,query(ql,qr,rt<<1,l,m),query(ql,qr,rt<<1|1,m+1,r),m,m-l+1,r-m);
  95. return res;
  96. }
  97. else if(ql<=m) return query(ql,qr,rt<<1,l,m);
  98. else return query(ql,qr,rt<<1|1,m+1,r);
  99. }
  100. int main()
  101. {
  102. // freopen("bzoj3995.in","r",stdin);
  103. // freopen("bzoj3995.out","w",stdout);
  104. for(int i=1;i<=500000;++i);
  105. scanf("%d%d",&n,&m);
  106. for(int i=0;i<2;++i)
  107. for(int j=1;j<n;++j)
  108. scanf("%d",&heng[i][j]);
  109. for(int i=1;i<=n;++i)
  110. scanf("%d",&zong[i]);
  111. buildtree(1,1,n);
  112. // printf("%d\n",query(1,3,1,1,n).z1y1);
  113. // printf("%d\n",query(1,3,1,1,n).z1y0);
  114. // printf("%d\n",query(1,3,1,1,n).z0y1);
  115. // printf("%d\n",query(1,3,1,1,n).z0y02);
  116. // printf("%d\n",query(1,3,1,1,n).z0y03);
  117. char op[3];
  118. int x1,y1,x2,y2,val;
  119. for(;m;--m)
  120. {
  121. scanf("%s",op);
  122. if(op[0]=='C')
  123. {
  124. scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&val);
  125. if(y1==y2) update(y1,val,1,1,n);
  126. else
  127. {
  128. if(y1>y2) swap(y1,y2);
  129. heng[x1-1][y1]=val;
  130. update(y1,1,1,n);
  131. update(y2,1,1,n);
  132. }
  133. }
  134. else
  135. {
  136. scanf("%d%d",&y1,&y2);
  137. printf("%d\n",query(y1,y2,1,1,n).z1y1);
  138. }
  139. }
  140. return 0;
  141. }

【线段树】bzoj3995 [SDOI2015]道路修建的更多相关文章

  1. [bzoj3995] [SDOI2015]道路修建 线段树

    Description 某国有2N个城市,这2N个城市构成了一个2行N列的方格网.现在该国政府有一个旅游发展计划,这个计划需要选定L.R两列(L<=R),修建若干条专用道路,使得这两列之间(包括 ...

  2. bzoj3995[SDOI2015]道路修建

    http://www.lydsy.com/JudgeOnline/problem.php?id=3995 线段树维护连通性. 我们发现,对于一个区间[L,R],我们只需要知道(1,L),(2,L),( ...

  3. 【BZOJ3995】[SDOI2015]道路修建 线段树区间合并

    [BZOJ3995][SDOI2015]道路修建 Description  某国有2N个城市,这2N个城市构成了一个2行N列的方格网.现在该国政府有一个旅游发展计划,这个计划需要选定L.R两列(L&l ...

  4. [BZOJ 3995] [SDOI2015] 道路修建 【线段树维护连通性】

    题目链接:BZOJ - 3995 题目分析 这道题..是我悲伤的回忆.. 线段树维护连通性,与 BZOJ-1018 类似,然而我省选之前并没有做过  1018,即使它在 ProblemSet 的第一页 ...

  5. [SDOI2015]道路修建(线段树)

    题意:给定2行n列的四连通带权网格图,支持修改边权和查询第[l,r]列的最小生成树 题解:这是一道好题,要么SDOI2019中n=2的20pts怎么会“我抄我自己”?(当然NOIP2018“我抄我自己 ...

  6. 【XSY2528】道路建设 LCT 可持久化线段树

    题目描述 给你一个\(n\)个点\(m\)条边图,\(q\)个询问,每次问你边权在\([l,r]\)之间的边组成的最小生成树(森林)的边权和.强制在线. \(n,m,q\leq 100000\) 题解 ...

  7. 【LOJ】#2186. 「SDOI2015」道路修建

    题解 就是线段树维护一下转移矩阵 分成两种情况,一种是前面有两个联通块,一种是前面有一个联通块 从一个联通块转移到一个联通块 也就是新加一列的三个边选其中两条即可 从一个联通块转移到两个联通块 不连竖 ...

  8. 洛谷P2505||bzoj2750 [HAOI2012]道路 && zkw线段树

    https://www.luogu.org/problemnew/show/P2505 https://www.lydsy.com/JudgeOnline/problem.php?id=2750 神奇 ...

  9. 【洛谷P4319】 变化的道路 线段树分治+LCT

    最近学了一下线段树分治,感觉还蛮好用... 如果正常动态维护最大生成树的话用 LCT 就行,但是这里还有时间这一维的限制. 所以,我们就把每条边放到以时间为轴的线段树的节点上,然后写一个可撤销 LCT ...

随机推荐

  1. Android_AsyncTaskDemo之QQ记步数(画圆形图片知识)

    今天学习了AsyncTask Android 的异步机制.我简单的实现我的一个小小案例--qq记步数.然后穿插一个画圆形图片的知识点. 由于所学知识有限,目前我计数,还有排名等等我就简单的利用随机数实 ...

  2. centos 安装 maven

    1: 下载 maven    我采用的是 apache-maven-3.3.9-bin.tar.gz http://maven.apache.org/download.cgi 2:  解压  tar ...

  3. UML类图画法及其之间的几种关系(转)

    UML类图画法及其之间的几种关系 最近做重构项目,需要画一下类图,发现类图的画法及其之间的几种关系已经淡忘了很多,所以整理总结一下,有问题的地方大家可以一起讨论下. 文章目录如下: 类图画法 类之间的 ...

  4. logback logback.xml常用配置详解(三) <filter>

    <filter>: 过滤器,执行一个过滤器会有返回个枚举值,即DENY,NEUTRAL,ACCEPT其中之一.返回DENY,日志将立即被抛弃不再经过其他过滤器:返回NEUTRAL,有序列表 ...

  5. Android 7.0 UICC 分析(四)

    本文讲解SIMRecords /frameworks/opt/telephony/src/java/com/android/internal/telephony/uicc/SIMRecords.jav ...

  6. ajax的表单提交,与传送数据

    ajax的表单提交 $.ajax ({ url: "<%=basePath%>resource/addPortDetectOne.action", dataType: ...

  7. Frameset 框架集 导航栏 的使用

    在index.jsp中 使用jsp标签转发到制定页面 <body> <jsp:forward page="/admin/frame.jsp"></js ...

  8. [刘阳Java]_MyBatis_映射文件的常用标签总结_第5讲

    MyBatis中常用标签的总结,简单给出自己的总结 MyBatis映射文件中的标签使用介绍1.<select>:用于编写查询语句用的标签 id:表示当前<select>标签的唯 ...

  9. Arch Linux 简易打包指南

    本文时代久远,请参阅更可靠的:Arch User Repository (简体中文) - 分享和维护软件包 这两天给 Kreogist µ 打 Arch Linux 包,照着 wiki 跟着搞,同时在 ...

  10. ocfs2: 搭建环境

    OCFS2是基于共享磁盘的集群文件系统,它在一块共享磁盘上创建OCFS2文件系统,让集群中的其它节点可以对磁盘进行读写操作.OCFS2由两部分内容构成,一部分实现文件系统功能,位于VFS之下和Ext4 ...