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 ...
随机推荐
- 缓存:Memcached Redis
一.Memcached Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的 ...
- ABP框架数据迁移报错
问题描述:将项目从TFS载下来 然后敲update-database 进行数据迁移 提示:Update-Database : 无法将“Update-Database”项识别为 cmdlet.函数.脚 ...
- linux切换用户命令
1. 切换用户的命令为:su +username 2.从普通用户切换到root用户:sudo su 3.退回到原来的用户:exit命令或logout,或者ctrl+d 4.如果要切换到新用户的工作环境 ...
- $《利用Python进行数据分析》学习笔记系列——IPython
本文主要介绍IPython这样一个交互工具的基本用法. 1. 简介 IPython是<利用Python进行数据分析>一书中主要用到的Python开发环境,简单来说是对原生python交互环 ...
- 011_用eclipse打开hadoop1.2.1源码出现The method getSplits(JobConf, int) is undefined for the type Object错误
出现的错误截图: 此时Eclipse使用的jdk1.8,将编译环境改成jdk1.7就行了,解决. 没问题了. 下面观点是参考如下网址,未经验证.参考:http://blog.csdn.net/onei ...
- 【HackerRank】Game Of Rotation
题目连接:Game Of Rotation Mark is an undergraduate student and he is interested in rotation. A conveyor ...
- 【leetcode刷题笔记】Wildcard Matching
Implement wildcard pattern matching with support for '?' and '*'. '?' Matches any single character. ...
- 发送ajax请求实现上传图片显示在网页上
<?php // 1,通过超全局变量来获取files[上传的图片名称] $file = $_FILES["files"] // 2,在通过strrchr来获取图片的格式 $e ...
- HDU 3466 Proud Merchants 排序 背包
题意:物品有三个属性,价格p,解锁钱数下线q(手中余额>=q才有机会购买该商品),价值v.钱数为m,问购买到物品价值和最大. 思路:首先是个01背包问题,但购买物品受限所以应先排序.考虑相邻两个 ...
- 【P1947】笨笨当粉刷匠(DP+前缀和)
这个题乍一看觉得挺简单的,事实上却完全不是.首先,这个题看上去无脑直接刷就可以然而因为刷的次数远远大于木板的个数所以不行,然后开始考虑DP,自己一开始是这么想的,如果用f[t][i][j]表示刷t次时 ...