[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\) 题解 ...
随机推荐
- javascript中new操作符的原理
javascript中的new是一个语法糖,对于学过c++,java 和c#等面向对象语言的人来说,以为js里面是有类和对象的区别的,实现上js并没有类,一切皆对象,比java还来的彻底 new的过程 ...
- [题解] LuoguP4381 [IOI2008]Island
LuoguP4381 [IOI2008]Island Description 一句话题意:给一个基环树森林,求每棵基环树的直径长度的和(基环树的直径定义与树类似,即基环树上一条最长的简单路径),节点总 ...
- python脚本下载 Google Driver 文件
使用python脚本下载 Google Driver 文件 import yaml import sys import requests import os import re import tarf ...
- Mybatis实现条件查询(三)
1. 准备 请先完成Mybatis基本配置(一)的基本内容 2. 疑问 我们再Mybatis基本配置(一)中实现了按照商品ID进行查询商品信息,可是在实际应用中却很少出现根据ID来查询商品的情况.因为 ...
- Neo4j--节点的增删查改基本用法
注 node-name 和 label-name node-name 有点句柄的味道. 从面向对象来理解,label-name相当于一个类,node-name相当于这个类的对象. 类比关系型数据库的 ...
- Ubuntu Kylin 14.04LTS 开机后卡在登陆界面,可以进入字符界面,或者登陆后鼠标不显示但是管用
2014年4月27日,距离中期检查还有七天,基本上什么也没做,特别着急,雨已经下了快一天了,中午用美团外卖定的黄焖排骨,MD,什么玩意,那么一点点就18块钱,一看就不值五块钱,发誓再也不吃,最重要的是 ...
- php魔术常量,_CLASS_,_METHOD_,_FUNCTION_
_CLASS_: 返回当前类的类名 _METHOD_:返回当前类方法的方法名(并显示类的调用,类名::方法名) _FUNCTION_:返回当前函数的函数名 _FILE_:当前文件的绝对路径(包含_FI ...
- CSU_1414 Query On a Tree BFS序+DFS时间戳进行预处理
2014 csu校赛 I 题,比赛的时候拿着他看了几个小时愣是没弄出好的方法,我们也想过统计出每个root的节点总数,然后减去离它d层的子节点的数目,即为答案.但是因为树的存储是无序的,所以每次为了找 ...
- 解决 urxvt “unknown terminal type.”
登录到远程服务器上后,有时执行某些命令会提示unknown terminal type. 这是因为远程ssh不支持urxvt,执行 export TERM=xterm-256color 或者在远程主机 ...
- docker安装fastdfs与java客户端测试
一.docker 安装FastDFS 1.拉取镜像 docker pull morunchang/fastdfs 2.创建并启动tracker容器 docker run -d --name=track ...