FJUT3568 中二病也要敲代码(线段树维护区间连续最值)题解
题意:有一个环,有1~N编号,m次操作,将a位置的值改为b,问你这个环当前最小连续和多少(不能全取也不能不取)
思路:用线段树维护一个区间最值连续和。我们设出两个变量Lmin,Rmin,Mmin表示区间左边最小连续和,右边最小连续和,区间最小连续和,显然这可以通过这个方式更新维护。

现在我们已经可以维护一个区间最值连续和了,那么怎么求“环”的最小连续和呢?显然如果最小区间横跨1和n是不能表示出来的(比如最小区间是2,1,n,n-1之和),那么我们可以转化为求sum-Mmax即区间和减去区间最大值,那么显然最终答案是min( sum[1] - Mmax[1], Mmin[1] ),但由题意“不能全取也不能不取”,那么特判。
好久没做线段树维护连续区间的题了...
代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<cmath>
#include<map>
#include<set>
#include<vector>
using namespace std;
#define inf 0x3f3f3f3f
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define mem(a,b) memset(a,b,sizeof(a));
#define lowbit(x) x&-x;
typedef long long ll;
typedef unsigned long long ull;
const double eps = 1e-;
const int maxn = 1e5+;
const ll mod = 1e8+;
ll Lmax[maxn << ], Rmax[maxn << ], Mmax[maxn << ], sum[maxn << ];
ll Lmin[maxn << ], Rmin[maxn << ], Mmin[maxn << ];
ll a[maxn];
void push_up(int rt){
Lmax[rt] = max(Lmax[rt << ], sum[rt << ] + Lmax[rt << | ]);
Rmax[rt] = max(Rmax[rt << | ], sum[rt << | ] + Rmax[rt << ]);
Mmax[rt] = max(max(Mmax[rt << ], Mmax[rt << | ]), Rmax[rt << ] + Lmax[rt << | ]);
Lmin[rt] = min(Lmin[rt << ], sum[rt << ] + Lmin[rt << | ]);
Rmin[rt] = min(Rmin[rt << | ], sum[rt << | ] + Rmin[rt << ]);
Mmin[rt] = min(min(Mmin[rt << ], Mmin[rt << | ]), Rmin[rt << ] + Lmin[rt << | ]);
sum[rt] = sum[rt << ] + sum[rt << | ];
}
void build(int l, int r, int rt){
if(l == r){
Mmax[rt] = Rmax[rt] = Lmax[rt] = Mmin[rt] = Rmin[rt] = Lmin[rt] = sum[rt] = a[l];
return;
}
int m = (l + r) >> ;
build(l, m, rt << );
build(m + , r, rt << | );
push_up(rt);
}
void update(int pos, int l, int r, int v, int rt){
if(l == r){
Mmax[rt] = Rmax[rt] = Lmax[rt] = Mmin[rt] = Rmin[rt] = Lmin[rt] = sum[rt] = v;
return;
}
int m = (l + r) >> ;
if(pos <= m)
update(pos, l, m, v, rt << );
else
update(pos, m + , r, v, rt << | );
push_up(rt);
}
int main(){
int n, m, A;
ll B;
while(~scanf("%d", &n)){
for(int i = ; i <= n; i++){
scanf("%lld", &a[i]);
}
build(, n, );
scanf("%d", &m);
while(m--){
ll MAX, MIN, ans;
scanf("%d%lld", &A, &B);
update(A, , n, B, );
if(Mmax[] == sum[]){
ans = Mmin[];
}
else if(Mmin[] == sum[]){
ans = Mmin[] - Mmax[];
}
else{
ans = min(sum[] - Mmax[], Mmin[]);
}
printf("%lld\n", ans);
}
}
return ;
}
FJUT3568 中二病也要敲代码(线段树维护区间连续最值)题解的更多相关文章
- SPOJ - GSS1-Can you answer these queries I 线段树维护区间连续和最大值
SPOJ - GSS1:https://vjudge.net/problem/SPOJ-GSS1 参考:http://www.cnblogs.com/shanyr/p/5710152.html?utm ...
- Can you answer these queries I SPOJ - GSS1 (线段树维护区间连续最大值/最大连续子段和)
You are given a sequence A[1], A[2], ..., A[N] . ( |A[i]| ≤ 15007 , 1 ≤ N ≤ 50000 ). A query is defi ...
- POJ.2763 Housewife Wind ( 边权树链剖分 线段树维护区间和 )
POJ.2763 Housewife Wind ( 边权树链剖分 线段树维护区间和 ) 题意分析 给出n个点,m个询问,和当前位置pos. 先给出n-1条边,u->v以及边权w. 然后有m个询问 ...
- Can you answer these queries V SPOJ - GSS5 (分类讨论+线段树维护区间最大子段和)
recursion有一个整数序列a[n].现在recursion有m次询问,每次她想知道Max { A[i]+A[i+1]+...+A[j] ; x1 <= i <= y1 , x2 &l ...
- 线段树维护区间前k小
线段树维护区间前k小 $ solution: $ 觉得超级钢琴太麻烦?在这里线段树提供一条龙服务 . 咳咳,开始讲正题!这道题我们有一个和超级钢琴复杂度一样 $ ~O(~\sum x\times lo ...
- CodeForces - 587E[线段树+线性基+差分] ->(线段树维护区间合并线性基)
题意:给你一个数组,有两种操作,一种区间xor一个值,一个是查询区间xor的结果的种类数 做法一:对于一个给定的区间,我们可以通过求解线性基的方式求出结果的种类数,而现在只不过将其放在线树上维护区间线 ...
- BZOJ.1036 [ZJOI2008]树的统计Count ( 点权树链剖分 线段树维护和与最值)
BZOJ.1036 [ZJOI2008]树的统计Count (树链剖分 线段树维护和与最值) 题意分析 (题目图片来自于 这里) 第一道树链剖分的题目,谈一下自己的理解. 树链剖分能解决的问题是,题目 ...
- 滑动窗口(poj,线段树维护区间最值)
题目描述 现在有一堆数字共N个数字(N<=10^6),以及一个大小为k的窗口.现在这个从左边开始向右滑动,每次滑动一个单位,求出每次滑动后窗口中的最大值和最小值. 例如: The array i ...
- hdu_5726_GCD(线段树维护区间+预处理)
题目链接:hdu_5726_GCD 题意: 给你n个数(n<=1e5)然后m个询问(m<=1e5),每个询问一个区间,问你这个区间的GCD是多少,并且输出从1到n有多少个区间的GCD和这个 ...
随机推荐
- shader之法线变换
对于法线变换,进行非统一缩放时,如果使用跟变换顶点相同的变换矩阵来变换法线,则会得到错误的结果,即变换后的法线方向与平面不再垂直. 如何求得变换法线的矩阵呢: 转载请注明出处:http://www.c ...
- 《大话设计模式》c++实现 之策略模式
一.UML图 二.概念 策略模式:他定义了算法家族,分别封装起来,让他们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户. 三.优点 (1)策略模式是一种定义一系列算法的方法,从 ...
- html5-css的引入
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8&qu ...
- 2017-2018-2 20165215 实验二 Java面向对象程序设计
20165215 实验二 Java面向对象程序设计 一.实验报告封面 课程:Java程序设计 班级:1652班 姓名:张家佳 学号:20165215 指导教师:娄嘉鹏 实验日期:2018年4月16日 ...
- C++中set用法详解
1.关于set C++ STL 之所以得到广泛的赞誉,也被很多人使用,不只是提供了像vector, string, list等方便的容器,更重要的是STL封装了许多复杂的数据结构算法和大量常用数据结构 ...
- checkbox 全选效果
html部分 <p id="all">全选</p> <input type="checkbox" /><br/> ...
- GoldenGate 12.3 MA架构介绍系列(2) - 数据同步测试
安装配置可参考上一篇:http://www.cnblogs.com/margiex/p/8071957.html 安装完成之后,会自动启动ServiceManager服务,此时,可以通过浏览器访问. ...
- 为什么要使用yocto
作为灵活多变且经济高效的解决方案,嵌入式 Linux展现了巨大的价值,并广泛应用于消费电子设备.网络设备.零售点和行业应用程序.然而,广泛的应用也意味着多样化的业务需求,嵌入式解决方案开发人员必须构建 ...
- 今日总结(linux和plsql)
#case ...when语句(根据字段不同值显示不同结果) ##1)case ...when语句的使用方法一: 语法格式: case column_name when value1 then res ...
- crontab命令的使用方法
crontab命令常见于Unix和Linux的操作系统之中,用于设置周期性被执行的指令.该命令从标准输入设备读取指令,并将其存放于"crontab"文件中,以供之后读取和执行. 在 ...