[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\) 题解 ...
随机推荐
- 使用DOM4J生成XML文档
package xml; import java.io.FileOutputStream; import java.util.ArrayList; import java.util.List; imp ...
- scanf与gets
gets函数为什么不能读取字符就往下运行了 这里有一个共性的问题,就是 scanf 输入后,会遗留一个回车符,传递到下面的输入语句: 回车符就会被下面的输入语句接收,而结束了输入,这里就是一个错误的值 ...
- [GXYCTF2019]Ping Ping Ping
0x00 知识点 命令执行变量拼接 /?ip=127.0.0.1;a=g;cat$IFS$1fla$a.php 过滤bash用sh执行 echo$IFS$1Y2F0IGZsYWcucGhw|base6 ...
- C++ Opencv播放AVI
#include "cxcore.h" #include "cvcam.h" #include "windows.h" #include & ...
- Java算法练习——寻找两个有序数组的中位数
题目链接 题目描述 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 $O(log(m + n))$. 你可以假设 nu ...
- 洛谷 P2719 搞笑世界杯
题目传送门 解题思路: f[i][j]表示买i张A票,j张B票的概率. AC代码: #include<iostream> #include<cstdio> using name ...
- BIOS与UEFI
BIOS BIOS是英文"Basic Input Output System"的缩略词,直译过来后中文名称就是"基本输入输出系统".在IBM PC兼容系统上,是 ...
- C语言I作业博客07
这个作业属于那个课程 C语言程序设计II 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/CST2019-1/homework/9935 我在这个课程的目 ...
- reference-based measure|Distribution-based measure|密码子使用偏向性
生命组学 密码子使用偏向性是指同义密码子使用频率不同. 影响因素:1.GC2.横向基因转移3.selection 转录偏好于多的tRNA. 同种氨基酸但有密码子使用偏向. ============== ...
- SQL注入——报错注入
0x00 背景 SQL注入长期位于OWASP TOP10 榜首,对Web 安全有着很大的影响,黑客们往往在注入过程中根据错误回显进行判断,但是现在非常多的Web程序没有正常的错误回显,这样就需要我们利 ...