Description

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

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

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

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

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

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

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

Input

输入文件的第一行包含一个整数N,表示梯子总共含有2N个点,第一行从左至右分别标号为1,3,……,2N-1,第二行从左至右分别标号为2,4,……,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. 有关最短路上的第k小/大值的总结

    1.USACO08JAN  Telephone Lines 题面 由于问的是最大值最小,所以二分加验证就好了 比较显然的,题干问的是第k+1长的路最短: 那么二分答案是正确的方向: 但是怎么验证? 我 ...

  2. 用python操作mysql数据库

    数据库的安装和连接 PyMySQL的安装 pip install PyMySQL python连接数据库 import pymysql db = pymysql.connect("数据库ip ...

  3. luogu题解 P1462 【通往奥格瑞玛的道路】二分+spfa

    题目链接: https://www.luogu.org/problemnew/show/P1462 思路: 又是一道水题,很明显二分+最短路 而且这道题数据非常水,spfa有个小错误居然拿了91分还比 ...

  4. 104、验证Swarm数据持久性 (Swarm11)

    参考https://www.cnblogs.com/CloudMan6/p/8016994.html   上一节我们成功将 nfs 的volume挂载到 Service上,本节验证 Failover时 ...

  5. GitLab: Deploy keys are not allowed to push code.

    被这个问题坑了,大半天.写此博文,愿入坑的童鞋能及时托坑 一.当你第一次pull或者push gitlab远程项目的时候提示你一个该建立一个sshkey,此时你在客户端生成sshkey 二.切记要把这 ...

  6. Swift(三)基本运算符

    Swift支持大部分标准C语言的运算符,并且对许多特性进行改进来减少常规编码的错误.除了支持基本运算符外,Swift还提供了2个特殊的运算符,分别是:溢出运算符和区间运算符 首先看下基本运算符 imp ...

  7. redis集群启动和关闭脚本

    创建startall.sh /usr/local/redis/bin/redis-server /usr/local/redis/redis-cluster/7001/redis.conf /usr/ ...

  8. C语言 STL中qsort用法

    qsort函数包含在<stdlib.h>的头文件里. qsort函数声明如下:void qsort(void *base, size_t nmemb, size_t size, int(* ...

  9. logging:不喜欢写日志可不好哦

    logging模块简介 logging模块是python内置的标准模块,主要用于输出程序的运行日志. 可以设置输出日志的等级,日志保存路径,日志文件回滚等等. logging模块的基本使用 impor ...

  10. 终极之战:Linux & Windows

    1.开源 当你买了一辆车,但你看不到引擎盖下面是什么?当你使用Windows驱动系统时就是如此.但是,相比之下,Linux完全是一个开源项目.你可以看看Linux操作系统的源代码,这是一个优点.Lin ...