BZOJ4355: Play with sequence
BZOJ4355: Play with sequence
https://lydsy.com/JudgeOnline/problem.php?id=4355
分析:
- 模板题。
- 把\(2\)操作看成先区间加再区间取\(max\)。
- 查询转化成求最小值个数。
- 需要维护\(3\)个标记。
- 这里我比较naive地维护了三个标记,多维护了一个最小值需要加的值。
- 然后下传的时候对左右儿子判断是否应该下传。
- 实际上不需要,直接修改最小值即可。
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
using namespace std;
#define N 1200050
#define ls p<<1
#define rs p<<1|1
typedef long long ll;
const ll inf = 1ll<<60;
int n,m;
ll a[N],mn[N],ci[N],tag1[N],tag2[N],tag3[N];
int cnt[N],len[N];
void giv1(int p,ll v) {
tag1[p]=v;
tag2[p]=0;
tag3[p]=0;
mn[p]=v;
ci[p]=inf;
cnt[p]=len[p];
}
void giv2(int p,ll v) {
tag2[p]+=v;
mn[p]+=v;
ci[p]+=v;
}
void giv3(int p,ll v) {
tag3[p]+=v;
mn[p]+=v;
}
void pushdown(int p) {
if(tag1[p]!=-1) giv1(ls,tag1[p]),giv1(rs,tag1[p]),tag1[p]=-1;
if(tag2[p]) giv2(ls,tag2[p]),giv2(rs,tag2[p]),tag2[p]=0;
if(tag3[p]) {
if(mn[ls]+tag3[p]==mn[p]) giv3(ls,tag3[p]);
if(mn[rs]+tag3[p]==mn[p]) giv3(rs,tag3[p]);
tag3[p]=0;
}
}
void pushup(int p) {
mn[p]=min(mn[ls],mn[rs]);
if(mn[ls]==mn[rs]) ci[p]=min(ci[ls],ci[rs]),cnt[p]=cnt[ls]+cnt[rs];
else {
if(mn[ls]<mn[rs]) ci[p]=min(ci[ls],mn[rs]),cnt[p]=cnt[ls];
else ci[p]=min(ci[rs],mn[ls]),cnt[p]=cnt[rs];
}
}
void build(int l,int r,int p) {
tag1[p]=-1;
len[p]=r-l+1;
if(l==r) {
mn[p]=a[l];
ci[p]=inf;
cnt[p]=1;
return ;
}
int mid=(l+r)>>1;
build(l,mid,ls); build(mid+1,r,rs);
pushup(p);
}
void updadd(int l,int r,int x,int y,int v,int p) {
if(x<=l&&y>=r) {
giv2(p,v); return ;
}
int mid=(l+r)>>1;
pushdown(p);
if(x<=mid) updadd(l,mid,x,y,v,ls);
if(y>mid) updadd(mid+1,r,x,y,v,rs);
pushup(p);
}
void updcov(int l,int r,int x,int y,int v,int p) {
if(x<=l&&y>=r) {
giv1(p,v); return ;
}
int mid=(l+r)>>1;
pushdown(p);
if(x<=mid) updcov(l,mid,x,y,v,ls);
if(y>mid) updcov(mid+1,r,x,y,v,rs);
pushup(p);
}
void updmax(int l,int r,int x,int y,int p) {
if(mn[p]>=0) return ;
if(x<=l&&y>=r&&ci[p]>0) {
giv3(p,-mn[p]); return ;
}
if(l==r) {giv1(p,0); return ;}
int mid=(l+r)>>1;
pushdown(p);
if(x<=mid) updmax(l,mid,x,y,ls);
if(y>mid) updmax(mid+1,r,x,y,rs);
pushup(p);
}
int query(int l,int r,int x,int y,int p) {
if(x<=l&&y>=r) return (mn[p]==0)*cnt[p];
int mid=(l+r)>>1,re=0;
pushdown(p);
if(x<=mid) re+=query(l,mid,x,y,ls);
if(y>mid) re+=query(mid+1,r,x,y,rs);
return re;
}
int main() {
scanf("%d%d",&n,&m);
int i,opt,x,y,z;
for(i=1;i<=n;i++) scanf("%lld",&a[i]);
build(1,n,1);
while(m--) {
scanf("%d%d%d",&opt,&x,&y);
if(opt==1) {
scanf("%d",&z);
updcov(1,n,x,y,z,1);
}else if(opt==2) {
scanf("%d",&z);
updadd(1,n,x,y,z,1);
updmax(1,n,x,y,1);
}else {
printf("%d\n",query(1,n,x,y,1));
}
}
}
BZOJ4355: Play with sequence的更多相关文章
- 2018.07.30 bzoj4355: Play with sequence(线段树)
传送门 维护区间覆盖成非负数,区间变成max(xi+a,0)" role="presentation" style="position: relative;&q ...
- BZOJ4355: Play with sequence(吉司机线段树)
题意 题目链接 Sol 传说中的吉司机线段树??感觉和BZOJ冒险那题差不多,就是强行剪枝... 这题最坑的地方在于对于操作1,$C >= 0$, 操作2中需要对0取max,$a[i] > ...
- bzoj 4695: 最假女选手 && Gorgeous Sequence HDU - 5306 && (bzoj5312 冒险 || 小B的序列) && bzoj4355: Play with sequence
算导: 核算法 给每种操作一个摊还代价(是手工定义的),给数据结构中某些东西一个“信用”值(不是手动定义的,是被动产生的),摊还代价等于实际代价+信用变化量. 当实际代价小于摊还代价时,增加等于差额的 ...
- bzoj4355 Play with sequence(吉司机线段树)题解
题意: 已知\(n\)个数字,进行以下操作: \(1.\)区间\([L,R]\) 赋值为\(x\) \(2.\)区间\([L,R]\) 赋值为\(max(a[i] + x, 0)\) \(3.\)区间 ...
- Segment Tree Beats 区间最值问题
Segment Tree Beats 区间最值问题 线段树一类特殊技巧! 引出:CF671C Ultimate Weirdness of an Array 其实是考试题,改题的时候并不会区间取最值,区 ...
- 【BZOJ4355】Play with sequence 线段树
[BZOJ4355]Play with sequence Description 维护一个长度为N的序列a,现在有三种操作: 1)给出参数U,V,C,将a[U],a[U+1],...,a[V-1],a ...
- 【bzoj4355】Play with sequence 线段树区间最值操作
题目描述 维护一个长度为N的序列a,现在有三种操作: 1)给出参数U,V,C,将a[U],a[U+1],...,a[V-1],a[V]都赋值为C. 2)给出参数U,V,C,对于区间[U,V]里的每个数 ...
- BZOJ4355:Play with sequence——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4355 维护一个长度为N的序列a,现在有三种操作: 1)给出参数U,V,C,将a[U],a[U+1] ...
- oracle SEQUENCE 创建, 修改,删除
oracle创建序列化: CREATE SEQUENCE seq_itv_collection INCREMENT BY 1 -- 每次加几个 STA ...
随机推荐
- pyhton3 configparser模块
1 #!/usr/bin/env python 2 # coding=utf-8 3 __author__ = 'Luzhuo' 4 __date__ = '2017/5/26' 5 # config ...
- php基础知识测试总结
1.LAMP具体结构包括Linux系统,Apache服务器,MySQL数据库,PHP语言. WAMP具体结构包括Windows系统,Apache服务器,MySQL数据库,PHP语言. 2.B/S架构: ...
- $用python实现快速排序算法
本文主要介绍用python实现基本的快速排序算法,体会一下python的快排代码可以写得多么简洁. 1. 三言两语概括算法核心思想 先从待排序的数组中找出一个数作为基准数(取第一个数即可),然后将原来 ...
- flex label 换行
Flex中label换行有两种情况 在AS中赋值: label.text="Online\r\nResources" 在mxml中赋值: text="Online Res ...
- 用C#编写猜数、九九乘法表‘、迷宫
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...
- easy_install
一 setuptools 和easy_install setuptools:setuptools 是一组由PEAK(Python Enterprise Application Kit)开发的 Pyth ...
- tcp三次握手过程
TCP握手协议 在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接.第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确 ...
- Centos6.5安装Mysql5.6.10
1. 先卸载掉老版本的mysql(linux严格区分大小写,查找的时候加上-i参数,和mysql相关的全部要卸) [root@liuchao ~]# rpm -qa | grep -i mysqlMy ...
- springcloud-搭建服务注册中心
创建服务注册中心 1.创建一个springboot 命名为eureka-server 1)添加Eureka依赖 pom.xml <?xml version="1.0" enc ...
- java基础(5)-集合类1
集合的由来 数组是很常用的一种数据结构,但假如我们遇到以下这样的的问题: 容器长度不确定 能自动排序 存储以键值对方式的数据 如果遇到这样的情况,数组就比较难满足了,所以也就有了一种与数组类似的数据结 ...