题面

题解

相信大家写过的传统做法像这样:(这段代码蒯自Karry5307的题解

struct SegmentTree{
ll l,r,prefix,suffix,sum,maxn;
}; //... inline void update(ll node)
{
ll res;
tree[node].sum=tree[node<<1].sum+tree[(node<<1)|1].sum;
tree[node].maxn=max(tree[node<<1].maxn,tree[(node<<1)|1].maxn);
res=tree[node<<1].suffix+tree[(node<<1)|1].prefix;
tree[node].maxn=max(tree[node].maxn,res);
res=tree[node<<1].sum+tree[(node<<1)|1].prefix;
tree[node].prefix=max(tree[node<<1].prefix,res);
res=tree[node<<1].suffix+tree[(node<<1)|1].sum;
tree[node].suffix=max(tree[(node<<1)|1].suffix,res);
} //...

有没有觉得这种做法有些麻烦

这里将一种硬核做法:动态dp

这个部分参考了GKxx 的博客

引入广义矩阵乘法:

\[\mathrm{C} = \mathrm{A} * \mathrm{B} \Leftrightarrow \mathrm{C}_{i,j} = \max_k\left\{\mathrm{A}_{i,k} + \mathrm{B}_{k,j}\right\}
\]

这样的话,我们首先写出动态规划的柿子:

设\(f_i\)表示以\(i\)结尾的最大子段和,\(g_i\)表示\([1,i]\)的最大子段和

于是

\[\begin{aligned} f_i &= \max(f_{i-1} + a_i, a_i) \\ g_i &= \max(g_{i-1}, f_i) \end{aligned}
\]

欢乐地写出矩乘的柿子:

\[\begin{bmatrix}f_{i-1} & g_{i-1} & 0\end{bmatrix} \times\begin{bmatrix}a_i & a_i & -\infty\\-\infty & 0 & -\infty\\a_i & a_i & 0\end{bmatrix}=\begin{bmatrix}f_i & g_i & 0\end{bmatrix}
\]

妙哉

因为矩阵乘法具有结合律,于是可以用线段树维护

当然资瓷单点修改和查询区间最大子段和了

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#define RG register
#define file(x) freopen(#x".in", "r", stdin);freopen(#x".out", "w", stdout);
#define clear(x, y) memset(x, y, sizeof(x)); inline int read()
{
int data = 0, w = 1;
char ch = getchar();
while(ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
if(ch == '-') w = -1, ch = getchar();
while(ch >= '0' && ch <= '9') data = data * 10 + (ch ^ 48), ch = getchar();
return data * w;
} const int maxn(50010), INF(0x3f3f3f3f);
template<typename T> inline void chkmax(T &a, const T &b)
{ return (void) (a < b ? a = b : 0); }
struct Matrix
{
int a[3][3];
inline int *operator [] (const int &x) { return a[x]; }
inline const int *operator [] (const int &x) const { return a[x]; }
} mat[maxn << 2]; int n, Q, a[maxn]; inline Matrix operator * (const Matrix &a, const Matrix &b)
{
Matrix c; for(int i = 0; i < 3; i++) c[i][0] = c[i][1] = c[i][2] = -INF;
for(int i = 0; i < 3; i++)
for(int j = 0; j < 3; j++)
for(int k = 0; k < 3; k++)
chkmax(c[i][k], a[i][j] + b[j][k]);
return c;
} void build(int root = 1, int l = 1, int r = n)
{
if(l == r)
{
Matrix &o = mat[root]; o[0][1] = o[2][0] = o[2][1] = -INF;
o[0][0] = o[0][2] = o[1][0] = o[1][2] = a[l];
o[1][1] = o[2][2] = 0; return;
}
int mid = (l + r) >> 1, lson = root << 1, rson = lson | 1;
build(lson, l, mid), build(rson, mid + 1, r);
mat[root] = mat[lson] * mat[rson];
} void update(int id, int v, int root = 1, int l = 1, int r = n)
{
if(l == r) return (void)
(mat[root][0][0] = mat[root][0][2]
= mat[root][1][0] = mat[root][1][2] = v);
int mid = (l + r) >> 1, lson = root << 1, rson = lson | 1;
if(id <= mid) update(id, v, lson, l, mid);
else update(id, v, rson, mid + 1, r);
mat[root] = mat[lson] * mat[rson];
} Matrix query(int ql, int qr, int root = 1, int l = 1, int r = n)
{
if(ql <= l && r <= qr) return mat[root];
int mid = (l + r) >> 1, lson = root << 1, rson = lson | 1;
if(qr <= mid) return query(ql, qr, lson, l, mid);
if(ql > mid) return query(ql, qr, rson, mid + 1, r);
return query(ql, qr, lson, l, mid) * query(ql, qr, rson, mid + 1, r);
} int main()
{
n = read();
for(RG int i = 1; i <= n; i++) a[i] = read();
build(); Q = read();
while(Q--)
{
int opt = read(), x = read(), y = read();
if(opt)
{
Matrix ans = query(x, y);
printf("%d\n", std::max(ans[1][0], ans[1][2]));
}
else a[x] = y, update(x, y);
}
return 0;
}

SP1716 GSS3 - Can you answer these queries III的更多相关文章

  1. 线段树 SP1716 GSS3 - Can you answer these queries III

    SP1716 GSS3 - Can you answer these queries III 题意翻译 n 个数,q 次操作 操作0 x y把A_xAx 修改为yy 操作1 l r询问区间[l, r] ...

  2. SP1716 GSS3 - Can you answer these queries III(单点修改,区间最大子段和)

    题意翻译 nnn 个数, qqq 次操作 操作0 x y把 AxA_xAx​ 修改为 yyy 操作1 l r询问区间 [l,r][l, r][l,r] 的最大子段和 题目描述 You are give ...

  3. SP1716 GSS3 - Can you answer these queries III 线段树

    问题描述 [LG-SP1716](https://www.luogu.org/problem/SP1716] 题解 GSS 系列的第三题,在第一题的基础上带单点修改. 第一题题解传送门 在第一题的基础 ...

  4. SP1716 GSS3 - Can you answer these queries III - 动态dp,线段树

    GSS3 Description 动态维护最大子段和,支持单点修改. Solution 设 \(f[i]\) 表示以 \(i\) 为结尾的最大子段和, \(g[i]\) 表示 \(1 \sim i\) ...

  5. SPOJ GSS3 Can you answer these queries III[线段树]

    SPOJ - GSS3 Can you answer these queries III Description You are given a sequence A of N (N <= 50 ...

  6. 数据结构(线段树):SPOJ GSS3 - Can you answer these queries III

    GSS3 - Can you answer these queries III You are given a sequence A of N (N <= 50000) integers bet ...

  7. 【SP1716】GSS3 - Can you answer these queries III(动态DP)

    题目链接 之前用线段树写了一遍,现在用\(ddp\)再写一遍. #include <cstdio> #define lc (now << 1) #define rc (now ...

  8. 题解 SP1716 【GSS3 - Can you answer these queries III】

    \[ Preface \] 没有 Preface. \[ Description \] 维护一个长度为 \(n\) 的数列 \(A\) ,需要支持以下操作: 0 x y 将 \(A_x\) 改为 \( ...

  9. 题解【SP1716】GSS3 - Can you answer these queries III

    题目描述 You are given a sequence \(A\) of \(N (N <= 50000)\) integers between \(-10000\) and \(10000 ...

随机推荐

  1. UIButton的两种block传值方式

    UIButton的两种block传值方式 方式1 - 作为属性来传值 BlockView.h 与 BlockView.m // // BlockView.h // Block // // Create ...

  2. [翻译] TSMessages

    TSMessages https://github.com/KrauseFx/TSMessages This library provides an easy to use class to show ...

  3. UIWebView如何加载本地图片

    UIWebView如何加载本地图片 UIWebView加载本地图片是有实用价值的.比方说,有时候我们需要本地加载静态页来显示相关帮助信息,而这些帮助信息当中含有很多很多的富文本,用代码实现难度较大,这 ...

  4. iOS手势处理

    iOS手势处理 iOS手势有着如下几种: UITapGestureRecognizer UIPinchGestureRecognizer UIRotationGestureRecognizer UIS ...

  5. PHP-7的FPM服务的启动

    1.PHP 7的FPM服务位置:/ect/init.d/php7.0-fpm 2.启动:sudo service php7.0-fpm reload

  6. 如何从Microsoft web platform installer取得离线安装包

    有一架visual studio 2012的开发环境A由于某种原因无法链接internet, 于是乎安装officetoolsforvisual2012就有问题了. 从微软的官网上只可以下载 offi ...

  7. 【模块化】 RequireJS入门教程总结与推荐

    之所以学习RequireJS,肯定对 模块化有一定的理解.这里有几篇学习 RequireJS的文章,推荐给大家去学习. Javascript模块化编程(一):模块的写法 Javascript模块化编程 ...

  8. 【转】.NET Core基于. csproj 配置文件发布项目

    一.前言 .NET工具链在最新的Preview3版本中,引入了新的MSBuild项目系统,项目文件又回归了.csproj的XML文件来管理,项目文件.包引用.程序集引用..NET Core工具集.发布 ...

  9. 3、Django下载与简介

    第1节:MVC与MTV模型 1.1 MVC Web服务器开发领域里著名的MVC模式,所谓MVC就是把Web应用分为模型(M),控制器(C)和视图(V)三层,他们之间以一种插件式的.松耦合的方式连接在一 ...

  10. jQuery获取radio选中项checked的几种方法

    如何知道radio哪个选项被选中了,也就是获取checked的radio项.这是个很简单的任务,这里我总结了几个常用的方法,体验一下jQuery的灵活. 具体的 HTML 和 jQuery 代码可以右 ...