题解

就是线段树维护一下转移矩阵

分成两种情况,一种是前面有两个联通块,一种是前面有一个联通块

从一个联通块转移到一个联通块

也就是新加一列的三个边选其中两条即可

从一个联通块转移到两个联通块

不连竖着的那条边,横着的两条边转移一条短的即可

从两个联通块转移到一个联通块

新加的一列三个边全连上

从两个联通块转移到两个联通块

连上横着的两条边

代码

#include <bits/stdc++.h>
#define fi first
#define se second
#define pii pair<int,int>
#define pdi pair<db,int>
#define mp make_pair
#define pb push_back
#define enter putchar('\n')
#define space putchar(' ')
#define eps 1e-8
#define mo 974711
#define MAXN 60005
//#define ivorysi
using namespace std;
typedef long long int64;
typedef double db;
template<class T>
void read(T &res) {
res = 0;char c = getchar();T f = 1;
while(c < '0' || c > '9') {
if(c == '-') f = -1;
c = getchar();
}
while(c >= '0' && c <= '9') {
res = res * 10 + c - '0';
c = getchar();
}
res *= f;
}
template<class T>
void out(T x) {
if(x < 0) {x = -x;putchar('-');}
if(x >= 10) {
out(x / 10);
}
putchar('0' + x % 10);
}
int64 a[2][MAXN],b[MAXN];
int N,M;
struct Matrix {
int64 f[2][2];
Matrix() {
for(int i = 0 ; i < 2 ; ++i) for(int j = 0 ; j < 2 ; ++j) f[i][j] = 1e10;
}
friend Matrix operator * (const Matrix &a,const Matrix &b) {
Matrix c;
for(int i = 0 ; i < 2 ; ++i) {
for(int j = 0 ; j < 2 ; ++j) {
for(int k = 0 ; k < 2 ; ++k) {
c.f[i][j] = min(c.f[i][j],a.f[i][k] + b.f[k][j]);
}
}
}
return c;
}
};
struct node {
int l,r;Matrix m;
}tr[MAXN * 4];
void update(int u) {
tr[u].m = tr[u << 1].m * tr[u << 1 | 1].m;
}
Matrix Calc(int c) {
Matrix res;
res.f[0][1] = min(a[0][c - 1],a[1][c - 1]);
res.f[0][0] = min(a[0][c - 1] + a[1][c - 1],b[c] + min(a[0][c - 1],a[1][c - 1]));
res.f[1][0] = a[0][c - 1] + a[1][c - 1] + b[c];
res.f[1][1] = a[0][c - 1] + a[1][c - 1];
return res;
}
void build(int u,int l,int r) {
tr[u].l = l;tr[u].r = r;
if(l == r) {
tr[u].m = Calc(l);
return;
}
int mid = (l + r) >> 1;
build(u << 1,l,mid);
build(u << 1 | 1,mid + 1,r);
update(u);
}
void Change(int u,int pos) {
if(tr[u].l == tr[u].r) {tr[u].m = Calc(pos);return;}
int mid = (tr[u].l + tr[u].r) >> 1;
if(pos <= mid) Change(u << 1,pos);
else Change(u << 1 | 1,pos);
update(u);
}
Matrix Query(int u,int l,int r) {
if(tr[u].l == l && tr[u].r == r) return tr[u].m;
int mid = (tr[u].l + tr[u].r) >> 1;
if(r <= mid) return Query(u << 1,l,r);
else if(l > mid) return Query(u << 1 | 1,l,r);
else return Query(u << 1,l,mid) * Query(u << 1 | 1,mid + 1,r);
}
void Init() {
read(N);read(M);
for(int i = 0 ; i <= 1 ; ++i) {
for(int j = 1 ; j < N ; ++j) {
read(a[i][j]);
}
}
for(int j = 1 ; j <= N ; ++j) {
read(b[j]);
}
build(1,1,N);
}
void Solve() {
char op[5];
int l,r;int x0,y0,x1,y1;
int64 w;
for(int i = 1 ; i <= M ; ++i) {
scanf("%s",op + 1);
if(op[1] == 'Q') {
read(l);read(r);
if(l == r) {out(b[l]);enter;}
else {
Matrix t = Query(1,l + 1,r);
out(min(t.f[1][0],b[l] + t.f[0][0]));enter;
}
}
else {
read(x0);read(y0);read(x1);read(y1);read(w);
if(x0 == x1) {
if(y0 > y1) swap(y0,y1);
a[x0 - 1][y0] = w;
Change(1,y1);
}
else {
b[y0] = w;
Change(1,y0);
}
}
}
}
int main() {
#ifdef ivorysi
freopen("f1.in","r",stdin);
#endif
Init();
Solve();
}

【LOJ】#2186. 「SDOI2015」道路修建的更多相关文章

  1. 【LOJ】#2445. 「NOI2011」道路修建

    题解 看完题目我的第一个反应是--要求最小花费的方案?!怎么求??? 然后我把题读完了.好吧. 记录一下size就行,比NOIP普及组还要不如的题= = 代码 #include <iostrea ...

  2. LOJ #2183「SDOI2015」序列统计

    有好多好玩的知识点 LOJ 题意:在集合中选$ n$个元素(可重复选)使得乘积模$ m$为$ x$,求方案数对$ 1004535809$取模 $ n<=10^9,m<=8000且是质数,集 ...

  3. Loj #2529. 「ZJOI2018」胖

    Loj #2529. 「ZJOI2018」胖 题目描述 Cedyks 是九条可怜的好朋友(可能这场比赛公开以后就不是了),也是这题的主人公. Cedyks 是一个富有的男孩子.他住在著名的 The P ...

  4. Loj #2192. 「SHOI2014」概率充电器

    Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...

  5. Loj #3096. 「SNOI2019」数论

    Loj #3096. 「SNOI2019」数论 题目描述 给出正整数 \(P, Q, T\),大小为 \(n\) 的整数集 \(A\) 和大小为 \(m\) 的整数集 \(B\),请你求出: \[ \ ...

  6. Loj #3093. 「BJOI2019」光线

    Loj #3093. 「BJOI2019」光线 题目描述 当一束光打到一层玻璃上时,有一定比例的光会穿过这层玻璃,一定比例的光会被反射回去,剩下的光被玻璃吸收. 设对于任意 \(x\),有 \(x\t ...

  7. Loj #3089. 「BJOI2019」奥术神杖

    Loj #3089. 「BJOI2019」奥术神杖 题目描述 Bezorath 大陆抵抗地灾军团入侵的战争进入了僵持的阶段,世世代代生活在 Bezorath 这片大陆的精灵们开始寻找远古时代诸神遗留的 ...

  8. Loj #2542. 「PKUWC2018」随机游走

    Loj #2542. 「PKUWC2018」随机游走 题目描述 给定一棵 \(n\) 个结点的树,你从点 \(x\) 出发,每次等概率随机选择一条与所在点相邻的边走过去. 有 \(Q\) 次询问,每次 ...

  9. Loj #3059. 「HNOI2019」序列

    Loj #3059. 「HNOI2019」序列 给定一个长度为 \(n\) 的序列 \(A_1, \ldots , A_n\),以及 \(m\) 个操作,每个操作将一个 \(A_i\) 修改为 \(k ...

随机推荐

  1. MT【196】整数个数

    设函数$f(x)=x^2-2ax+15-2a$的两个零点分别为$x_1,x_2$, 且在区间$(x_1,x_2)$上恰好有两个正整数,则实数$a$的取值范围______ 提示:$1<|x_1-x ...

  2. 洛谷 P1344 [USACO4.4]追查坏牛奶Pollutant Control 解题报告

    P1344 [USACO4.4]追查坏牛奶Pollutant Control 题目描述 你第一天接手三鹿牛奶公司就发生了一件倒霉的事情:公司不小心发送了一批有三聚氰胺的牛奶.很不幸,你发现这件事的时候 ...

  3. bzoj3114 LCM Pair Sum

    题意:以质因数分解的方式给定n,求所有满足:lcm(a, b) = n的无序数对的价值和.其中(a, b)的价值为a + b 解: 定义首项为a,公比为q,项数为n的等比数列的和为getQ(a, q, ...

  4. 【总结】STL--map

    map支持以下功能: size():查询 map 中的 key 的个数 empty():判空 clear():清空 insert()/erase():插入/删除 find(x):查找 key 为 x ...

  5. 【洛谷P1122】最大子树和

    题目大意:给定一棵 N 个节点的无根树,点有点权,点权有正有负,求这棵树的联通块的最大权值之和是多少. 题解:设 \(dp[i]\) 表示以 i 为根节点的最大子树和,那么只要子树的 dp 值大于0, ...

  6. c 取读地图输入

    ][];     scanf("%ld%ld",&n,&m);     ;i<n;i++)         scanf("%s",mat[ ...

  7. laravel 单元测试设置模拟时间

    有时候我们需要对一些超时的逻辑进行测试,需要等待一定的时间来验证超时逻辑是否生效. Carbon 库提供了 setTestNow 方法来设置一个虚拟的当前时间 使用这个特性的前提是:我们的待测试代码利 ...

  8. Java基础-算术运算符(Arithmetic Operators)

    Java基础-算术运算符(Arithmetic Operators) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. Java程序通过运算符实现对数据的处理,Java中的运算符包括: ...

  9. CString的头文件

    CString的头文件:#include <atlstr.h>

  10. Spark记录-本地Spark读取Hive数据简单例子

    注意:将mysql的驱动包拷贝到spark/lib下,将hive-site.xml拷贝到项目resources下,远程调试不要使用主机名 import org.apache.spark._ impor ...