题意:给定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]道路修建(线段树)的更多相关文章

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

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

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

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

  3. 【线段树】bzoj3995 [SDOI2015]道路修建

    线段树每个结点维护5个域: 整个区间的MST. 将两个左端点连通,两个右端点不连通,整个区间内选择2*(r-l+1)-2条边的最小生成森林,有两个连通块. 将两个右端点连通,两个左端点不连通,整个区间 ...

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

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

  5. bzoj3995[SDOI2015]道路修建

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

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

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

  7. LOJ #2831. 「JOISC 2018 Day 1」道路建设 线段树+Link-cut-tree

    用 LCT 维护颜色相同连通块,然后在线段树上查一下逆序对个数就可以了. code: #include <cstdio> #include <algorithm> #inclu ...

  8. BZOJ 2435:[Noi2011]道路修建(树型DP)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2435 题意:中文题意. 思路:很简单的树形DP,sz记录儿子有多少个和cur记录走的哪条弧,然后直接 ...

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

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

随机推荐

  1. javascript中new操作符的原理

    javascript中的new是一个语法糖,对于学过c++,java 和c#等面向对象语言的人来说,以为js里面是有类和对象的区别的,实现上js并没有类,一切皆对象,比java还来的彻底 new的过程 ...

  2. [题解] LuoguP4381 [IOI2008]Island

    LuoguP4381 [IOI2008]Island Description 一句话题意:给一个基环树森林,求每棵基环树的直径长度的和(基环树的直径定义与树类似,即基环树上一条最长的简单路径),节点总 ...

  3. python脚本下载 Google Driver 文件

    使用python脚本下载 Google Driver 文件 import yaml import sys import requests import os import re import tarf ...

  4. Mybatis实现条件查询(三)

    1. 准备 请先完成Mybatis基本配置(一)的基本内容 2. 疑问 我们再Mybatis基本配置(一)中实现了按照商品ID进行查询商品信息,可是在实际应用中却很少出现根据ID来查询商品的情况.因为 ...

  5. Neo4j--节点的增删查改基本用法

    注 node-name 和  label-name node-name 有点句柄的味道. 从面向对象来理解,label-name相当于一个类,node-name相当于这个类的对象. 类比关系型数据库的 ...

  6. Ubuntu Kylin 14.04LTS 开机后卡在登陆界面,可以进入字符界面,或者登陆后鼠标不显示但是管用

    2014年4月27日,距离中期检查还有七天,基本上什么也没做,特别着急,雨已经下了快一天了,中午用美团外卖定的黄焖排骨,MD,什么玩意,那么一点点就18块钱,一看就不值五块钱,发誓再也不吃,最重要的是 ...

  7. php魔术常量,_CLASS_,_METHOD_,_FUNCTION_

    _CLASS_: 返回当前类的类名 _METHOD_:返回当前类方法的方法名(并显示类的调用,类名::方法名) _FUNCTION_:返回当前函数的函数名 _FILE_:当前文件的绝对路径(包含_FI ...

  8. CSU_1414 Query On a Tree BFS序+DFS时间戳进行预处理

    2014 csu校赛 I 题,比赛的时候拿着他看了几个小时愣是没弄出好的方法,我们也想过统计出每个root的节点总数,然后减去离它d层的子节点的数目,即为答案.但是因为树的存储是无序的,所以每次为了找 ...

  9. 解决 urxvt “unknown terminal type.”

    登录到远程服务器上后,有时执行某些命令会提示unknown terminal type. 这是因为远程ssh不支持urxvt,执行 export TERM=xterm-256color 或者在远程主机 ...

  10. docker安装fastdfs与java客户端测试

    一.docker 安装FastDFS 1.拉取镜像 docker pull morunchang/fastdfs 2.创建并启动tracker容器 docker run -d --name=track ...