AcWing:245. 你能回答这些问题吗(线段树最大子段和)
给定长度为N的数列A,以及M条指令,每条指令可能是以下两种之一:
1、“1 x y”,查询区间 [x,y] 中的最大连续子段和,即 maxx≤l≤r≤ymaxx≤l≤r≤y{∑ri=lA[i]∑i=lrA[i]}。
2、“2 x y”,把 A[x] 改成 y。
对于每个查询指令,输出一个整数表示答案。
输入格式
第一行两个整数N,M。
第二行N个整数A[i]。
接下来M行每行3个整数k,x,y,k=1表示查询(此时如果x>y,请交换x,y),k=2表示修改。
输出格式
对于每个查询指令输出一个整数表示答案。
每个答案占一行。
数据范围
N≤500000,M≤100000N≤500000,M≤100000
输入样例:
5 3
1 2 -3 4 5
1 2 3
2 2 -1
1 3 2
输出样例:
2
-1
算法:线段树最大子段和
代码:
#include <iostream>
#include <cstdio> using namespace std; #define INF 0x3f3f3f3f const int maxn = 5e5+; struct node {
int ms; //存储当前区间最大子段和
int lmax; //左边得前缀和
int rmax //右边得前缀和
int sum; //这个区间的总和
}tree[maxn << ]; int arr[maxn];
int n, m; void pushup(int root) { //参数的解释:
tree[root].sum = tree[root << ].sum + tree[root << | ].sum; //左子数的总和 + 右子树的总和
tree[root].lmax = max(tree[root << ].lmax, tree[root << ].sum + tree[root << | ].lmax); //左子数左边得前缀和,左子数得总和 + 右子树左边的前缀和
tree[root].rmax = max(tree[root << | ].rmax, tree[root << | ].sum + tree[root << ].rmax); //右子树右边的前缀和,右子树的总和 + 左子数右边的前缀和
tree[root].ms = max(max(tree[root << ].ms, tree[root << | ].ms), tree[root << ].rmax + tree[root << | ].lmax); //左子树的区间最大子段和,右子树的区间最大子段和,左子数右边的前缀和 + 右子树左边的前缀和
} void build(int root, int l ,int r) {
if(l == r) {
tree[root].sum = arr[l];
tree[root].ms = arr[l];
tree[root].lmax = arr[l];
tree[root].rmax = arr[l];
return;
}
int mid = (l + r) >> ;
build(root << , l ,mid);
build(root << | , mid + , r);
pushup(root);
} void update(int root, int l, int r, int x, int y) {
if(l == r) {
tree[root].sum = y;
tree[root].ms = y;
tree[root].lmax = y;
tree[root].rmax = y;
return;
}
int mid = (l + r) >> ;
if(x <= mid) {
update(root << , l, mid, x, y);
} else {
update(root << | , mid + , r, x, y);
}
pushup(root);
} struct node query(int root, int l, int r, int x, int y) {
if(x <= l && r <= y) {
return tree[root];
}
int mid = (l + r) >> ;
struct node a, b, c;
//首先初始化,因为有可能进入第一种或者是第二种情况,那么其中有一个变量就用不到
a.ms = a.lmax = a.rmax = a.sum = -INF;
b.ms = b.lmax = b.rmax = b.sum = -INF;
c.ms = c.lmax = c.rmax = -INF;
c.sum = ;
//分三种情况:
if(x <= mid && y <= mid) {
a = query(root << , l, mid, x, y);
c.sum += a.sum;
} else if(x > mid && y > mid) {
b = query(root << | , mid + , r, x, y);
c.sum += b.sum;
} else {
a = query(root << , l, mid, x, y);
b = query(root << | , mid + , r, x, y);
c.sum += a.sum + b.sum;
}
//解释同上...
c.ms = max(c.ms, max(a.rmax + b.lmax, max(a.ms, b.ms)));
c.lmax = max(c.lmax, max(a.lmax, a.sum + b.lmax));
c.rmax = max(c.rmax, max(b.rmax, b.sum + a.rmax));
return c;
} int main() {
scanf("%d %d", &n, &m);
for(int i = ; i <= n; i++) {
scanf("%d", &arr[i]);
}
build(, , n);
while(m--) {
int q, x, y;
scanf("%d %d %d", &q, &x, &y);
if(q == ) {
if(x > y) { //题目中有解释...
swap(x, y);
}
printf("%d\n", query(, , n, x, y).ms);
} else {
update(, ,n, x, y);
}
}
return ;
}
AcWing:245. 你能回答这些问题吗(线段树最大子段和)的更多相关文章
- Acwing 245.你能回答这些问题吗
题目描述 给定长度为N的数列A,以及M条指令,每条指令可能是以下两种之一: 1."1 x y",查询区间 [x,y] 中的最大连续子段和,即 maxx≤l≤r≤y{∑ri=lA[i ...
- ACwing 你能回答这些问题吗(线段树求最大连续字段和)
给定长度为N的数列A,以及M条指令,每条指令可能是以下两种之一: 1.“1 x y”,查询区间 [x,y] 中的最大连续子段和,即 maxx≤l≤r≤ymaxx≤l≤r≤y{∑ri=lA[i]∑i=l ...
- acwing 243. 一个简单的整数问题2 树状数组 线段树
地址 https://www.acwing.com/problem/content/description/244/ 给定一个长度为N的数列A,以及M条指令,每条指令可能是以下两种之一: 1.“C l ...
- AcWing 243. 一个简单的整数问题2 (树状数组)打卡
题目:https://www.acwing.com/problem/content/244/ 题意:区间加,区间查询 思路:我们把原先那个差分数组分解一下 ∑i=1x∑j=1ib[j]=∑i=1x(x ...
- AcWing:242. 一个简单的整数问题(树状数组)
给定长度为N的数列A,然后输入M行操作指令. 第一类指令形如“C l r d”,表示把数列中第l~r个数都加d. 第二类指令形如“Q X”,表示询问数列中第x个数的值. 对于每个询问,输出一个整数表示 ...
- AcWing:148. 合并果子(哈夫曼树)
在一个果园里,达达已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆. 达达决定把所有的果子合成一堆. 每一次合并,达达可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和. 可以看出 ...
- AcWing 107. 超快速排序(归并排序 + 逆序对 or 树状数组)
在这个问题中,您必须分析特定的排序算法----超快速排序. 该算法通过交换两个相邻的序列元素来处理n个不同整数的序列,直到序列按升序排序. 对于输入序列9 1 0 5 4,超快速排序生成输出0 1 4 ...
- AcWing:246. 区间最大公约数(线段树 + 增量数组(树状数组) + 差分序列)
给定一个长度为N的数列A,以及M条指令,每条指令可能是以下两种之一: 1.“C l r d”,表示把 A[l],A[l+1],…,A[r] 都加上 d. 2.“Q l r”,表示询问 A[l],A[l ...
- AcWing 247. 亚特兰蒂斯 (线段树,扫描线,离散化)
题意:给你\(n\)个矩形,求矩形并的面积. 题解:我们建立坐标轴,然后可以对矩形的横坐标进行排序,之后可以遍历这些横坐标,这个过程可以想像成是一条线从左往右扫过x坐标轴,假如这条线是第一次扫过矩形的 ...
随机推荐
- C++实用模板 | 党办大活动计分
#include <iostream> #include <cmath> #include <cstring> #include <string> #i ...
- SKCTF管理系统
一开始是一个简洁风的登录界面 康康注册界面 嗯...也是很简洁风呢. 那让我们来查看元素(fn+f12) 没有什么有flag的迹象呢! 那我们试一下注册一个账号 这时候我们已经有解题的线索了: 获得管 ...
- excel批量修改文件名称
步骤: 1. 然后将标准号所在的列复制三份到旁边相邻的空白列 2. 使用方方格子让三列中最左面的列只保存如下格式的数据: DB37/T或DB37/ 3. 使用方方格子让三列中中间的列的只保存如下格式的 ...
- javaScript的Array方法
仅个人总结 声明方法: var arr = new Array(); var arr = new Array(1,2,3,4,5); var arr = new array(size);//当为一个参 ...
- 计算机网络:这是一份全面 & 详细 的TCP协议学习指南
原文链接:blog.csdn.net 用这个媒体播放器组件,实时互动时也可共同观看本地视频juejin.im 前言 计算机网络基础 该是程序猿需掌握的知识,但往往会被忽略 今天,我将详细讲解计算机网络 ...
- vue项目-axios封装、easy-mock使用
vue全家桶概括下来就是 项目构建工具(vue-cli) 路由(vue-router) 状态管理(vuex) http请求工具 vue有自己的http请求工具插件vue-resource,但是vue2 ...
- JVM--对象访问和OutOfMemoryError异常
对象访问: 使用句柄访问方式: 使用直接指针访问方式: OutOfMemoryError异常: 设置堆的最小最大容量:-Xms20m -Xmx20m 设置一样推不可自动扩展. 设置出现内存溢出 ...
- 转载:elasticsearch入门篇
转自:https://www.cnblogs.com/hello-shf/p/11543408.html elasticsearch入门篇 elasticsearch专栏:https://www. ...
- 树莓派wifi环境下初始化及环境配置
在此放一下我的系统 链接:https://pan.baidu.com/s/192cL6qSsMd-wqxHeDWfIug 提取码:0lrq 1.准备一张内存卡,最好是32G class10 16G的话 ...
- 从一道索引数据结构面试题看B树、B+树
题目1: Mysql数据库用过吧?l里面的索引是基于什么数据结构. 答:主要是基于Hash表和B+树 题目2: 很好请你说一下B+树的实现细节是什么样的?B-树和B+树有什么区别?联合索引在B+树中如 ...