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简单验证码识别

    在学习python通过接口自动登录网站时,用户名密码.cookies.headers都好解决但是在碰到验证码这个时就有点棘手了:于是通过网上看贴,看官网完成了对简单验证码的识别,如果是复杂的请看大神的 ...

  2. python_线程读写操作<一>

    线程读写操作 import threading,random,queue q = queue.Queue() alist=[] def shengchan(): for i in range(10): ...

  3. C#中static修饰符的作用

    static在C#中表示的是静态的,比如一个静态的字段是归类型所有,而非归对象所有,也就是说,在调用这个字段时,只能用类型去调,而不能用对象. 实例字段时随着对象创建而创建,对象销毁而销毁,而静态字段 ...

  4. JS基础_基本语法

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  5. LintCode 29---交叉字符串

    public class Solution { /** * @param s1: A string * @param s2: A string * @param s3: A string * @ret ...

  6. AngularJS 在实际应用中优缺点

    AngularJS 在实际应用中优点:模板功能强大丰富,并且是声明式的,自带了丰富的Angular指令:是一个比较完善的前端MV*框架,包含模板,数据双向绑定,路由,模块化,服务,过滤器,依赖注入等所 ...

  7. C# 之 String.Empty

    .NET Framework 类库,表示空字符串,此字段为只读,命名空间:System.程序集:mscorlib(在 mscorlib.dll 中).   EG:protected string lo ...

  8. Java高并发程序设计学习笔记(二):多线程基础

    转自:https://blog.csdn.net/dataiyangu/article/details/86226835# 什么是线程?线程的基本操作线程的基本操作新建线程调用run的一种方式调用ru ...

  9. 月薪 30K Java 程序员,需要掌握哪些技术?

    转载自:Java3y 1-5年的Java程序员,薪资区间大致是在15-25K左右,那有没有可能提前达到30K的薪资呢?有人说这只能是大企业或者互联网企业工程师才能拿到.也许是的,小公司或者非互联网企业 ...

  10. 在vs上开发linux c++

    https://www.cnblogs.com/xylc/p/6533716.html?&from=androidqq https://www.jianshu.com/p/8b51a795cb ...