Description

有一个神秘好人跟Bdcxq玩一个游戏,如果Bdcxq成功完成了这个游戏,那么他将会得到一件礼物。
这个游戏是这样的:
有一个梯子形的图如下,每条边都有一个权值。

神秘好人一开始会告诉Bdcxq每条边的权值。

然后神秘好人会做这样的事情:

1.神秘好人会修改某条边的权值;

2.神秘老人会问你从一个点走到另一个点所需经过边权和最小的权值和。

如果Bdcxq一直能答对问题,那么他就完成了游戏,也能得到礼物。

现在他请你编一个程序来帮他完成游戏。

Input

输入文件的第一行包含一个整数N,表示梯子总共含有2N个点,第一行从左至右分别标号为13,……,2N-1第二行从左至右分别标号为24,……,2N

接下来有三行。

第一行有N-1个整数,依次表示上层相邻两点间的初始权值。

第二行有N个整数,依次表示两层之间的边的初始权值。

第三行有N-1个整数,依次表示下层相邻两点间的初始权值。

接下来一行包含一个整数M,表示神秘好人在游戏开始后的操作。

接下来M行:

每行第一个整数若是0,表示这是一个修改操作,接下来会有3个整数Ai,Bi,Ci,Ai为0,1,2分别代表这条边属于上层边,中间边和下层边,Bi表示这条边是这一层从左向右数的第Bi条边,Ci表示要修改成的边权。

每行第一个整数若是1,表示这是一个询问操作,接下来会有2个整数Ai,Bi,询问Ai到Bi的经过边的最小权值和。

Output

对于每次询问操作你需要输出一行包含一个整数,为最小的边权值和。

Sample Input

4
1 2 7
1 3 4 8
4 5 6
5
1 1 2
1 2 6
1 1 8
0 1 3 1
1 1 8

Sample Output

1
8
13
10

HINT

100%的数据满足N,M≤ 100000。

Solution

用线段树维护仅在这个区间内走时四个角的最短路的邻接矩阵,然后修改询问就强行维护一波就好啦。这题细节比较多,要注意一下。。。

Code

 #include <cstdio>
#include <cstring>
#include <algorithm> #define R register
#define maxn 100010
#define cmin(_a, _b) (_a > (_b) ? _a = (_b) : 0)
#define dmin(_a, _b) ((_a) < (_b) ? (_a) : (_b))
typedef long long ll;
struct Data {
ll d[][];
inline void init()
{
memset(d, , sizeof (d));
for (R int i = ; i < ; ++i) d[i][i] = ;
}
inline void floyd()
{
for (R int k = ; k < ; ++k)
for (R int i = ; i < ; ++i)
for (R int j = ; j < ; ++j)
cmin(d[i][j], d[i][k] + d[k][j]);
}
inline Data operator + (const Data &that) const
{
R Data ret; ret.init();
ret.d[][] = ret.d[][] = dmin(d[][], d[][] + that.d[][] + d[][]);
ret.d[][] = ret.d[][] = dmin(that.d[][], that.d[][] + d[][] + that.d[][]); ret.d[][] = ret.d[][] = dmin(d[][] + that.d[][], d[][] + that.d[][]);
ret.d[][] = ret.d[][] = dmin(d[][] + that.d[][], d[][] + that.d[][]);
ret.d[][] = ret.d[][] = dmin(d[][] + that.d[][], d[][] + that.d[][]);
ret.d[][] = ret.d[][] = dmin(d[][] + that.d[][], d[][] + that.d[][]);
// ret.floyd();
return ret;
}
} ;
int u[maxn], m[maxn], d[maxn];
Data tr[maxn << ];
void update(R int o)
{
tr[o] = tr[o << ] + tr[o << | ];
}
void build(R int o, R int l, R int r)
{
if (l == r)
{
tr[o].init();
tr[o].d[][] = tr[o].d[][] = m[l];
tr[o].d[][] = tr[o].d[][] = u[l];
tr[o].d[][] = tr[o].d[][] = d[l];
tr[o].d[][] = tr[o].d[][] = m[l + ];
tr[o].floyd();
return ;
}
R int mid = l + r >> ;
build(o << , l, mid);
build(o << | , mid + , r);
update(o);
}
int ql, qr;
void modify(R int o, R int l, R int r)
{
if (l == r)
{
tr[o].init();
tr[o].d[][] = tr[o].d[][] = m[l];
tr[o].d[][] = tr[o].d[][] = u[l];
tr[o].d[][] = tr[o].d[][] = d[l];
tr[o].d[][] = tr[o].d[][] = m[l + ];
tr[o].floyd();
return ;
}
R int mid = l + r >> ;
if (ql <= mid) modify(o << , l, mid);
else modify(o << | , mid + , r);
update(o);
}
Data query(R int o, R int l, R int r)
{
if (ql <= l && r <= qr) return tr[o];
R Data ret;
R int mid = l + r >> ;
if (ql <= mid && qr <= mid) return query(o << , l, mid);
if (mid < ql && mid < qr) return query(o << | , mid + , r);
return query(o << , l, mid) + query(o << | , mid + , r);
}
int main()
{
R int n; scanf("%d", &n);
for (R int i = ; i < n; ++i) scanf("%d", u + i);
for (R int i = ; i <= n; ++i) scanf("%d", m + i);
for (R int i = ; i < n; ++i) scanf("%d", d + i);
build(, , n - );
R int q; scanf("%d", &q);
for (; q; --q)
{
R int opt, a, b, c; scanf("%d%d%d", &opt, &a, &b);
if (!opt)
{
scanf("%d", &c);
if (a == ) u[b] = c;
else if (a == ) m[b] = c;
else d[b] = c; if (a != || b != n) ql = b, modify(, , n - );
if (a == && b != ) ql = b - , modify(, , n - );
}
else
{
R int l = (a + ) >> , lt = (a + ) & , r = (b + ) >> , rt = (b + ) & ;
l > r ? std::swap(l, r), std::swap(lt, rt), : ; R Data v1, v2, v3; v1.init(); v2.init(); v3.init();
ql = , qr = l - ;
if (ql <= qr) v1 = query(, , n - );
ql = l; qr = r - ;
if (ql <= qr) v2 = query(, , n - );
ql = r; qr = n - ;
if (ql <= qr) v3 = query(, , n - ); R ll ans = ;
if (l == r)
{
ans = dmin(v1.d[ + lt][ + rt], v3.d[lt][rt]);
}
else
{
// for (R int i = 0; i < 4; ++i, puts("")) for (R int j = 0; j < 4; ++j) printf("%d ", v1.d[i][j]);
// for (R int i = 0; i < 4; ++i, puts("")) for (R int j = 0; j < 4; ++j) printf("%d ", v2.d[i][j]);
// for (R int i = 0; i < 4; ++i, puts("")) for (R int j = 0; j < 4; ++j) printf("%d ", v3.d[i][j]);
ans = v2.d[lt][ + rt];
cmin(ans, v1.d[][] + v2.d[lt ^ ][ + rt]);
cmin(ans, v2.d[lt][ + (rt ^ )] + v3.d[][]);
cmin(ans, v1.d[][] + v2.d[lt ^ ][ + (rt ^ )] + v3.d[][]);
/* cmin(v2.d[0][1], v1.d[2][3]);
cmin(v2.d[2][3], v3.d[0][1]);
v2.floyd();
ans = v2.d[lt][2 + rt];*/
}
printf("%lld\n", ans);
}
}
return ;
}
/*
4
1 2 7
1 3 4 8
4 5 6
5
1 1 2
1 2 6
1 1 8
0 1 3 1
1 1 8
*/

【BZOJ2459】 [BeiJing2011]神秘好人的更多相关文章

  1. BZOJ2459 : [BeiJing2011]神秘好人

    线段树每个节点维护d[4][4]表示四个顶点之间的最短路,合并时用Floyed合并,查询时分三段然后合并. #include<cstdio> #define N 100010 struct ...

  2. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  3. 神秘代理-Proxy

    前言: 代理模式作为常见的设计模式之一,在项目开发中不可或缺.本文就尝试着揭开代理的神秘面纱,也欢迎各路人批评指正! 1.如何实现代理: [假设有个关于汽车移动(move)的计时需求]设计:Movea ...

  4. 深入理解javascript对象系列第三篇——神秘的属性描述符

    × 目录 [1]类型 [2]方法 [3]详述[4]状态 前面的话 对于操作系统中的文件,我们可以驾轻就熟将其设置为只读.隐藏.系统文件或普通文件.于对象来说,属性描述符提供类似的功能,用来描述对象的值 ...

  5. BZOJ 2462: [BeiJing2011]矩阵模板

    2462: [BeiJing2011]矩阵模板 Time Limit: 2 Sec  Memory Limit: 128 MBSubmit: 915  Solved: 432[Submit][Stat ...

  6. [BZOJ4408][Fjoi 2016]神秘数

    [BZOJ4408][Fjoi 2016]神秘数 试题描述 一个可重复数字集合S的神秘数定义为最小的不能被S的子集的和表示的正整数.例如S={1,1,1,4,13},1 = 12 = 1+13 = 1 ...

  7. 在c++这片神秘的大陆上

    在c++这片神秘的大陆上,有一个无往而不利的地下王国,据说其手段血腥残忍,却深得民心,因为,他们是侠,是剑胆琴心,诗肠酒骨的侠客,他们不知解决了多少疑难杂症,除去了多少问题漏洞,而他们的首领-> ...

  8. 揭开GrowingIO无埋点的神秘面纱

    揭开GrowingIO无埋点的神秘面纱   早在研究用户行为分析的时候,就发现国内的GrowingIO在宣传无埋点技术,最近正好抽出时间来研究一下所谓的无埋点到底是什么样的. 我分六部分来分析一下无埋 ...

  9. [bzoj4408][Fjoi2016]神秘数

    Description 一个可重复数字集合$S$的神秘数定义为最小的不能被$S$的子集的和表示的正整数. 例如$S={1,1,1,4,13}$, $1=1$, $2=1+1$, $3=1+1+1$, ...

随机推荐

  1. python函数 -- 作用域,异常处理

    1.def语句和参数 python定义函数的关键词为def,格式如下: def 函数名([变元],[变元],....)          #保存在变元中的值,在函数返回后该变元就会被销毁了. 2.返回 ...

  2. 剑指offer-构建乘积数组-数组-python

    题目描述 给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1].不 ...

  3. golang(4):函数 & 数组 & 切片 & map & 锁

    内置函数 // 1. close:主要用来关闭channel // 2. len:用来求长度,比如string.array.slice.map.channel // 3. new:用来分配内存,主要用 ...

  4. 虚拟机无法启动,提示:无法打开内核功能扩展“com.vmware.kext.vmci”: 无此文件或目录

    打开 系统偏好设置->安全性与隐私->允许打开 即可

  5. 08 Python之内存管理

    python中的内存管理,从浅层次来说,可以分为3个方面来讲: 1,引用计数: python中引用计数,为了跟踪内存的对象 当创建对象的时候即被引用了,当对象不再被使用时,即某个对象的引用计数为0,它 ...

  6. 解决 webpack 打包文件体积过大

    webpack 把我们所有的文件都打包成一个 JS 文件,这样即使你是小项目,打包后的文件也会非常大.下面就来讲下如何从多个方面进行优化. 去除不必要的插件 刚开始用 webpack 的时候,开发环境 ...

  7. se37 函数中的异常使用

    一种是rase <exceptions> FUNCTION ztest. *"-------------------------------------------------- ...

  8. LLVM源码安装教程

    LLVM4.0源码安装教程 环境:ubuntu16.04 llvm-4.0 clang-4.0 步骤: 1.依赖库安装,注意llvm的编译对gcc版本和cmake版本有要求,请根据版本进行匹配 $ s ...

  9. 转载: Ubuntu 在命令下,安装中文环境的方法。

    转载: https://blog.csdn.net/zhangchao19890805/article/details/52743380 安装英文版ubuntu,在打开含有中文字符文件时会乱码,有需要 ...

  10. el-table + el-form实现可编辑表格字段验证

    表格输入信息很常见,因此表格的验证也很必要,el-form提供了输入框验证.可以和表格结合起来用,使用效果     HTML: <div class="table_box"& ...