线段树

先看前三个操作,都是区间修改,我们对于信息维护一个二元组(a,b),表示x=max(x+a,b),那么第一个操作就是(a,-inf),第二个是(-a,0),第三个是(-inf,a)

然后看查询,第一个就是维护所有信息,那么考虑合并标记,(a,b)=(max(a1+a2,-inf),max(max(b1+a2,-inf),b2)),这里和-inf取max是为了防止溢出

然后是最后一个查询,其实就是相当于最大前缀和,那么我们考虑维护这个东西,每次下来标记,设为(f,g),f是父节点的最大子段和,g是总和,那么ff=max(max(ff->a,tt->a+f->a,max(tt->b,f->b)),就是可以取原来的和原来的和加上新的操作,可以取max,因为我们希望的是最大值。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 5e5 + ;
const ll inf = 1e16;
inline ll rd()
{
ll x = , f = ; char c = getchar();
while(c < '' || c > '') { if(c == '-') f = -; c = getchar(); }
while(c >= '' && c <= '') { x = x * + c - ''; c = getchar(); }
return x * f;
}
int n, m;
ll a[N];
struct node {
ll A, B;
node() { A = ; B = -inf; }
node(ll _, ll __) : A(_), B(__) {}
node friend max(const node &a, const node &b) {
return node(max(a.A, b.A), max(a.B, b.B));
}
node friend operator + (const node &a, const node &b) {
return node(max(a.A + b.A, -inf), max(max(a.B + b.A, -inf), b.B));
}
bool Null()
{
return A == && B == -inf;
}
} T[N << ], F[N << ];
void paint(int x, node f, node t)
{
F[x] = max(F[x], T[x] + f);
T[x] = T[x] + t;
}
void pd(int x)
{
if(F[x].Null() && T[x].Null()) return;
paint(x << , F[x], T[x]);
paint(x << | , F[x], T[x]);
F[x] = T[x] = node(, -inf);
}
void modify(int l, int r, int x, int a, int b, node t)
{
if(l > b || r < a) return;
if(l >= a && r <= b)
{
paint(x, t, t);
return;
}
pd(x);
int mid = (l + r) >> ;
modify(l, mid, x << , a, b, t);
modify(mid + , r, x << | , a, b, t);
}
int query(int l, int r, int x, int p)
{
if(l == r) return x;
pd(x);
int mid = (l + r) >> ;
if(p <= mid) return query(l, mid, x << , p);
else return query(mid + , r, x << | , p);
}
int main()
{
n = rd();
m = rd();
for(int i = ; i <= n; ++i) a[i] = rd();
while(m--)
{
int opt = rd(), l, r, x;
if(opt == )
{
l = rd();
r = rd();
x = rd();
modify(, n, , l, r, node(x, -inf));
}
if(opt == )
{
l = rd();
r = rd();
x = rd();
modify(, n, , l, r, node(-x, ));
}
if(opt == )
{
l = rd();
r = rd();
x = rd();
modify(, n, , l, r, node(-inf, x));
}
if(opt == )
{
l = rd();
x = query(, n, , l);
printf("%lld\n", max(a[l] + T[x].A, T[x].B));
}
if(opt == )
{
l = rd();
x = query(, n, , l);
printf("%lld\n", max(a[l] + F[x].A, F[x].B));
}
}
return ;
}

bzoj5117的更多相关文章

随机推荐

  1. 【Unity3D自学记录】Unity3D之自制小钟表

    今天来写一个小钟表,事实上非常easy,就运用到了欧拉角. 首先创建时钟.分钟.秒钟以及4个点(12点.3点.6点.9点)偷懒了~~没弄那么多点. 时钟.分钟.秒钟这三个父级的中心一定要注意,我们旋转 ...

  2. start-dfs.sh 和 start-all.sh的区别

    start-dfs.sh 只启动namenode 和datanode, start-all.sh还包括yarn的resourcemanager 和nodemanager 之前就所以因为只启动了star ...

  3. 抽象类的子类能够new

    纠结了半天,我以为继承了Activity后不能new这里被那个onCreate方法迷惑了以为会出现故障一直没直接创建对象类使用 后来试了试才知道 activity似乎是一个抽象类吧. 你要用他的方法, ...

  4. ElasticSearch 分页检索

    在ElasticSearch的多索引和多类别里说到我们在集群中有14个文档匹配我们的(空)搜索语句.单数仅仅有10个文档在hits数组中.我们怎样看到其它文档? 和SQL使用LIMITkeyword返 ...

  5. sed系列:行或者模式匹配删除特定行

    “p” command prints the buffer (remember to use -n option with “p”) “d” command is just opposite, its ...

  6. Spring Boot中使用RSocket

    1. 概述 RSocket应用层协议支持 Reactive Streams语义, 例如:用RSocket作为HTTP的一种替代方案.在本教程中, 我们将看到RSocket用在spring boot中, ...

  7. dubbo 实战1

    准备:先安装zookeeper,然后进入一下步骤 服务端 1.新建 maven项目 2.pom.xml 内容如下 <?xml version="1.0" encoding=& ...

  8. Java8新特性(一)概览

    最近看了好几段Java代码和以往的风格很不一样,都有点不太适应了,后来一查原来是Java8的新特性. 为了保持对技术的敏感性(面试...),这里我们一起来学习下Java8的新特性. 如果从技术角度来看 ...

  9. kernel.panic

    sysctl -a kernel.panic = 0kernel.panic_on_io_nmi = 0kernel.panic_on_oops = 1kernel.panic_on_stackove ...

  10. 操作系统 资源管理 zookeeper yarn 进程管理 分布式 yarn诞生背景

    zookeeper 信息保管员 YARN 简介 https://www.ibm.com/developerworks/cn/data/library/bd-yarn-intro/index.html