题目描述

给你一个序列,支持三种操作:

$0\ x\ y\ t$ :将 $[x,y]$ 内大于 $t$ 的数变为 $t$ ;
$1\ x\ y$ :求 $[x,y]$ 内所有数的最大值;
$2\ x\ y$ :求 $[x,y]$ 内所有数的和。

多组测试数据,$\sum n,\sum m\le 10^6$


题解

线段树区间最值操作

对于线段树上的一个节点,维护对应区间的:最大值 $mx$ 、最大值个数 $c$ 及严格次大值 $se$ 。那么对于一次区间最小值操作:

如果 $t\ge mx$ ,则这个操作不会对区间产生影响,直接退出;
如果 $se<t<mx$ ,则这个操作只会对区间最大值产生影响,区间和减小 $c(mx-t)$ ,最大值变为 $t$ ,打标记退出;
否则,无法直接计算贡献,递归子树处理。

其中第二种情况的 “打标记” 实际上就是下传新的最大值,因此可以不打标记,直接将最大值下传。

这样做的时间复杂度是 $O(n\log n)$ 的,证明参考 吉老师的Segment tree Beats!

#include <cstdio>
#include <algorithm>
#define N 1000010
#define lson l , mid , x << 1
#define rson mid + 1 , r , x << 1 | 1
using namespace std;
typedef long long ll;
ll mx[N << 2] , c[N << 2] , se[N << 2] , sum[N << 2];
inline void vmin(ll v , int x)
{
if(mx[x] > v) sum[x] -= c[x] * (mx[x] - v) , mx[x] = v;
}
inline void pushup(int x)
{
int l = x << 1 , r = x << 1 | 1;
sum[x] = sum[l] + sum[r];
if(mx[l] > mx[r]) mx[x] = mx[l] , c[x] = c[l] , se[x] = max(se[l] , mx[r]);
if(mx[l] < mx[r]) mx[x] = mx[r] , c[x] = c[r] , se[x] = max(mx[l] , se[r]);
if(mx[l] == mx[r]) mx[x] = mx[l] , c[x] = c[l] + c[r] , se[x] = max(se[l] , se[r]);
}
inline void pushdown(int x)
{
vmin(mx[x] , x << 1) , vmin(mx[x] , x << 1 | 1);
}
void build(int l , int r , int x)
{
if(l == r)
{
scanf("%lld" , &mx[x]) , sum[x] = mx[x] , c[x] = 1 , se[x] = -1;
return;
}
int mid = (l + r) >> 1;
build(lson) , build(rson);
pushup(x);
}
void update(int b , int e , ll v , int l , int r , int x)
{
if(mx[x] <= v) return;
if(b <= l && r <= e && se[x] < v)
{
vmin(v , x);
return;
}
pushdown(x);
int mid = (l + r) >> 1;
if(b <= mid) update(b , e , v , lson);
if(e > mid) update(b , e , v , rson);
pushup(x);
}
ll qmax(int b , int e , int l , int r , int x)
{
if(b <= l && r <= e) return mx[x];
pushdown(x);
int mid = (l + r) >> 1;
ll ans = 0;
if(b <= mid) ans = max(ans , qmax(b , e , lson));
if(e > mid) ans = max(ans , qmax(b , e , rson));
return ans;
}
ll qsum(int b , int e , int l , int r , int x)
{
if(b <= l && r <= e) return sum[x];
pushdown(x);
int mid = (l + r) >> 1;
ll ans = 0;
if(b <= mid) ans += qsum(b , e , lson);
if(e > mid) ans += qsum(b , e , rson);
return ans;
}
int main()
{
int T;
scanf("%d" , &T);
while(T -- )
{
int n , m , opt , x , y;
ll z;
scanf("%d%d" , &n , &m);
build(1 , n , 1);
while(m -- )
{
scanf("%d%d%d" , &opt , &x , &y);
if(opt == 0) scanf("%lld" , &z) , update(x , y , z , 1 , n , 1);
if(opt == 1) printf("%lld\n" , qmax(x , y , 1 , n , 1));
if(opt == 2) printf("%lld\n" , qsum(x , y , 1 , n , 1));
}
}
return 0;
}

【hdu5306】Gorgeous Sequence 线段树区间最值操作的更多相关文章

  1. HDU 5306 Gorgeous Sequence[线段树区间最值操作]

    Gorgeous Sequence Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

  2. 【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]里的每个数 ...

  3. 【bzoj4695】最假女选手 线段树区间最值操作

    题目描述 给定一个长度为 N 序列,编号从 1 到 N .要求支持下面几种操作:1.给一个区间[L,R] 加上一个数x 2.把一个区间[L,R] 里小于x 的数变成x 3.把一个区间[L,R] 里大于 ...

  4. HUD.2795 Billboard ( 线段树 区间最值 单点更新 单点查询 建树技巧)

    HUD.2795 Billboard ( 线段树 区间最值 单点更新 单点查询 建树技巧) 题意分析 题目大意:一个h*w的公告牌,要在其上贴公告. 输入的是1*wi的w值,这些是公告的尺寸. 贴公告 ...

  5. Codeforces Round #250 (Div. 1) D. The Child and Sequence 线段树 区间取摸

    D. The Child and Sequence Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest ...

  6. cf834D(dp+线段树区间最值,区间更新)

    题目链接: http://codeforces.com/contest/834/problem/D 题意: 每个数字代表一种颜色, 一个区间的美丽度为其中颜色的种数, 给出一个有 n 个元素的数组, ...

  7. HDU 3911 Black And White(线段树区间合并+lazy操作)

    开始以为是水题,结果...... 给你一些只有两种颜色的石头,0为白色,1为黑色. 然后两个操作: 1 l r 将[ l , r ]内的颜色取反 0 l r 计算[ l , r ]内最长连续黑色石头的 ...

  8. UVA 1400."Ray, Pass me the dishes!" -分治+线段树区间合并(常规操作+维护端点)并输出最优的区间的左右端点-(洛谷 小白逛公园 升级版)

    "Ray, Pass me the dishes!" UVA - 1400 题意就是线段树区间子段最大和,线段树区间合并,但是这道题还要求输出最大和的子段的左右端点.要求字典序最小 ...

  9. HDU-1754I Hate It 线段树区间最值

    这道题比较基本,就是用线段树维护区间最值,可以算是模板吧-.. I Hate It Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768 ...

随机推荐

  1. css首行缩进2个字符

    css设置: p{ text-indent:2em; }

  2. WPF MVVM从入门到精通6:RadioButton等一对多控件的绑定

    原文:WPF MVVM从入门到精通6:RadioButton等一对多控件的绑定   WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通2:实现一个登录窗口 WPF MVVM ...

  3. 【LG3238】 [HNOI2014]道路堵塞

    题目描述 给你一张\(N\)个点.\(M\)条边的有向图,按顺序给定你一条有\(L\)条边的\(1\rightarrow n\)的最短路, 每次断掉这\(L\)条边中的一条(不对后面答案产生影响),求 ...

  4. Apache入门篇(一)之安装部署apache

    一.HTTPD特性 (1)高度模块化:core(核心) + modules(模块) = apache(2)动态模块加载DSO机制: Dynamic Shared Object(动态共享对象)(3)MP ...

  5. linux安装PHP-memcache-redis扩展

    1.php memcache 扩展 http://pecl.php.net/package/memcache/3.0.8 下载文件源码 #tar zxvf memcache-3.0.8.tar#/us ...

  6. C#Framework4.0支持异步async/await语法

    由于用户使用的是XP系统,但是程序里异步都是通过async/await代码来实现的,然而async/await需要Framework4.5版本才可以,而XP系统最高只能支持到Framework4.0, ...

  7. eclipse查看源代码问题

    最近分析源代码时,eclipse总是出错,显示org.eclipse.core.runtime.CoreException,解决方法:在builderpath点击 add external jars, ...

  8. 【视频编解码·学习笔记】4. H.264的码流封装格式 & 提取NAL有效数据

    一.码流封装格式简单介绍: H.264的语法元素进行编码后,生成的输出数据都封装为NAL Unit进行传递,多个NAL Unit的数据组合在一起形成总的输出码流.对于不同的应用场景,NAL规定了一种通 ...

  9. 转:为什么说招到合适的人比融到钱更加重要 - Hiring Great Talent is More Important Than Fund Raising

    我在猎头行业工作了 20 多年,一直在帮助创业公司招聘优秀的人才.我服务过的客户既有 VC 投资的初创企业,也有即将 IPO 的公司.我和 200 多个 VC 合作过,也见过 300 多个客户失败的案 ...

  10. Yii2 UploadedFile上传文件

    通过 UploadFile::getInstance($model, $attribute); UploadFile::getInstances($model, $attribute); Upload ...