[SDOI2015]道路修建(线段树)
题意:给定2行n列的四连通带权网格图,支持修改边权和查询第[l,r]列的最小生成树
题解:这是一道好题,要么SDOI2019中n=2的20pts怎么会“我抄我自己”?(当然NOIP2018“我抄我自己”除外,因为那是想给大家送分,而且NOIP2018的质量有多烂大家自己心里清楚)
对于区间[l,r],其实只需维护第l列和第r列共4个点的连通性,以及满足连通的最小代价。维护的是MST最左、最右边的竖线位置,横线的最大值,左端点到最左边竖线中横线最大值,右端点到最右边竖线中横线的最大值,以及最小生成树(即答案)5个变量,建议开结构体。而情况比较多,讨论起来有些麻烦。
还有这道题要注意的是,每次从[l,r]应该递归到[l,mid][mid,r]两个区间,因为要维护的是连通块长度至少为2的连通块。
#include<bits/stdc++.h>
#define lson l,mid,rt<<1
#define rson mid,r,rt<<1|1
using namespace std;
const int N=;
struct node{int l,r,lmx,rmx,mx,s;}tr[N<<];
int n,m,c[N],v[N][];
void pushup(int rt,int lc,int rc)
{
tr[rt].mx=max(tr[lc].mx,tr[rc].mx);
tr[rt].s=tr[lc].s+tr[rc].s;
tr[rt].l=tr[lc].l,tr[rt].lmx=tr[lc].lmx;
tr[rt].r=tr[rc].r,tr[rt].rmx=tr[rc].rmx;
int mx=max(tr[lc].rmx,tr[rc].lmx);
if(tr[lc].r==tr[rc].l)tr[rt].s-=c[tr[lc].r];
else if(mx>=max(c[tr[lc].r],c[tr[rc].l]))tr[rt].s-=mx;
else if(c[tr[lc].r]>c[tr[rc].l])
{
tr[rt].s-=c[tr[lc].r];
if(tr[lc].l==tr[lc].r)tr[rt].l=tr[rc].l,tr[rt].lmx=max(tr[lc].mx,tr[rc].lmx);
}
else{
tr[rt].s-=c[tr[rc].l];
if(tr[rc].l==tr[rc].r)tr[rt].r=tr[lc].r,tr[rt].rmx=max(tr[rc].mx,tr[lc].rmx);
}
}
void build(int l,int r,int rt)
{
if(l+==r)
{
tr[rt].mx=max(v[l][],v[l][]);
if(tr[rt].mx>=max(c[l],c[r]))
{
tr[rt].l=l,tr[rt].r=r,tr[rt].lmx=tr[rt].rmx=;
tr[rt].s=v[l][]+v[l][]+c[l]+c[r]-tr[rt].mx;
}
else if(c[l]>c[r])
{
tr[rt].l=tr[rt].r=r,tr[rt].lmx=tr[rt].mx,tr[rt].rmx=;
tr[rt].s=v[l][]+v[l][]+c[r];
}
else{
tr[rt].l=tr[rt].r=l,tr[rt].rmx=tr[rt].mx,tr[rt].lmx=;
tr[rt].s=v[l][]+v[l][]+c[l];
}
return;
}
int mid=l+r>>;
build(lson),build(rson);
pushup(rt,rt<<,rt<<|);
}
void update(int L,int R,int l,int r,int rt)
{
if(L>R)return;
if(l+==r)
{
tr[rt].mx=max(v[l][],v[l][]);
if(tr[rt].mx>=max(c[l],c[r]))
{
tr[rt].l=l,tr[rt].r=r,tr[rt].lmx=tr[rt].rmx=;
tr[rt].s=v[l][]+v[l][]+c[l]+c[r]-tr[rt].mx;
}
else if(c[l]>c[r])
{
tr[rt].l=tr[rt].r=r,tr[rt].lmx=tr[rt].mx,tr[rt].rmx=;
tr[rt].s=v[l][]+v[l][]+c[r];
}
else{
tr[rt].l=tr[rt].r=l,tr[rt].rmx=tr[rt].mx,tr[rt].lmx=;
tr[rt].s=v[l][]+v[l][]+c[l];
}
return;
}
int mid=l+r>>;
update(L,min(R,mid),lson);
update(max(L,mid),R,rson);
pushup(rt,rt<<,rt<<|);
}
node query(int L,int R,int l,int r,int rt)
{
if(L==l&&r==R)return tr[rt];
int mid=l+r>>;
if(R<=mid)return query(L,R,lson);
if(L>=mid)return query(L,R,rson);
node u=query(L,mid,lson),v=query(mid,R,rson);
tr[(N<<)-]=u,tr[(N<<)-]=v;
pushup((N<<)-,(N<<)-,(N<<)-);
return tr[(N<<)-];
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<n;i++)scanf("%d",&v[i][]);
for(int i=;i<n;i++)scanf("%d",&v[i][]);
for(int i=;i<=n;i++)scanf("%d",&c[i]);
build(,n,);
while(m--)
{
char op;cin>>op;
if(op=='Q')
{
int l,r;node u;scanf("%d%d",&l,&r);
if(l==r)printf("%d\n",c[l]);
else u=query(l,r,,n,),printf("%d\n",u.s);
}
else{
int x1,y1,x2,y2,z;
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&z);
if(x1>x2)swap(x1,x2);
if(y1>y2)swap(y1,y2);
if(x1==x2)v[y1][x1-]=z;else c[y2]=z;
update(y1,y2,,n,);
}
}
}
[SDOI2015]道路修建(线段树)的更多相关文章
- 【BZOJ3995】[SDOI2015]道路修建 线段树区间合并
[BZOJ3995][SDOI2015]道路修建 Description 某国有2N个城市,这2N个城市构成了一个2行N列的方格网.现在该国政府有一个旅游发展计划,这个计划需要选定L.R两列(L&l ...
- [bzoj3995] [SDOI2015]道路修建 线段树
Description 某国有2N个城市,这2N个城市构成了一个2行N列的方格网.现在该国政府有一个旅游发展计划,这个计划需要选定L.R两列(L<=R),修建若干条专用道路,使得这两列之间(包括 ...
- 【线段树】bzoj3995 [SDOI2015]道路修建
线段树每个结点维护5个域: 整个区间的MST. 将两个左端点连通,两个右端点不连通,整个区间内选择2*(r-l+1)-2条边的最小生成森林,有两个连通块. 将两个右端点连通,两个左端点不连通,整个区间 ...
- [BZOJ 3995] [SDOI2015] 道路修建 【线段树维护连通性】
题目链接:BZOJ - 3995 题目分析 这道题..是我悲伤的回忆.. 线段树维护连通性,与 BZOJ-1018 类似,然而我省选之前并没有做过 1018,即使它在 ProblemSet 的第一页 ...
- bzoj3995[SDOI2015]道路修建
http://www.lydsy.com/JudgeOnline/problem.php?id=3995 线段树维护连通性. 我们发现,对于一个区间[L,R],我们只需要知道(1,L),(2,L),( ...
- 洛谷P2505||bzoj2750 [HAOI2012]道路 && zkw线段树
https://www.luogu.org/problemnew/show/P2505 https://www.lydsy.com/JudgeOnline/problem.php?id=2750 神奇 ...
- LOJ #2831. 「JOISC 2018 Day 1」道路建设 线段树+Link-cut-tree
用 LCT 维护颜色相同连通块,然后在线段树上查一下逆序对个数就可以了. code: #include <cstdio> #include <algorithm> #inclu ...
- BZOJ 2435:[Noi2011]道路修建(树型DP)
http://www.lydsy.com/JudgeOnline/problem.php?id=2435 题意:中文题意. 思路:很简单的树形DP,sz记录儿子有多少个和cur记录走的哪条弧,然后直接 ...
- 【XSY2528】道路建设 LCT 可持久化线段树
题目描述 给你一个\(n\)个点\(m\)条边图,\(q\)个询问,每次问你边权在\([l,r]\)之间的边组成的最小生成树(森林)的边权和.强制在线. \(n,m,q\leq 100000\) 题解 ...
随机推荐
- JVM探秘:jinfo查看JVM运行时参数
本系列笔记主要基于<深入理解Java虚拟机:JVM高级特性与最佳实践 第2版>,是这本书的读书笔记. 如何查看JVM运行时参数,对于线上JVM调优是很关键的,因为只有知道了当前使用的JVM ...
- 适合初学者的10个linux命令
转http://devopscube.com/list-of-linux-commands-every-developer-should-know/ At some point in you deve ...
- HZNU-ACM寒假集训Day6小结 线性DP
线性DP 考虑一组硬币面值 1,5,11 给定W,求凑出W的最少硬币个数 我们记凑出n需要用到的最少硬币数量为f(n) 我们注意到了一个很棒的性质 : f(n)只与f(n-1) f(n-5) f( ...
- salt教程1-理解saltstack
https://docs.saltstack.com/en/getstarted/system/index.html 1 基本介绍 通过观察它的实际运行,你可以大致理解salt如何工作.这意味着,在控 ...
- (递归)P1025 数的划分
题解: #include<iostream>using namespace std;int ret=0,m_n;void p(int n,double k,int j){ if(k==1) ...
- 201771010123汪慧和《面向对象程序设计Java》第十二周实验总结
一.理论部分 1.在Java提供的GUI构建工具中可以分为组件和容器两类. 2.在Java中的组件有:按钮.标签.复选框.单选按钮.选择框.列表框.文本框.滚动条.画布.菜单. 3.在Java中的容器 ...
- 一天一个设计模式——(Singleton)单例模式(线程安全性)
一.模式说明 有时候,我们希望在应用程序中,仅生成某个类的一个实例,这时候需要用到单例模式. 二.模式类图 三.模式中的角色 Singleton角色,该模式中仅有的一个角色,该角色有一个返回唯一实例的 ...
- SpringBoot+Shiro+DB (二)
之前我们完成了Spring+Shiro的最基本配置搭建,现在我们再增加上DB,毕竟没有哪个系统会将用户.角色.权限等信息硬编码到代码里.DB选用myslq. 数据库准备 脚本如下.依然是两个用户:ad ...
- C++ 一个exe的两个运行实例之间共享数据
#pragma data_seg("Shared") volatile int iNum = 0; #pragma data_seg() #pragma comment(linke ...
- 合并两个word文档,保持样式不变
一.需求说明 例如将封面插入到word正文上方 二.导入依赖 <dependency> <groupId>org.apache.poi</groupId> < ...