【hdu5306】Gorgeous Sequence 线段树区间最值操作
给你一个序列,支持三种操作:
$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 线段树区间最值操作的更多相关文章
- HDU 5306 Gorgeous Sequence[线段树区间最值操作]
Gorgeous Sequence Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Othe ...
- 【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]里的每个数 ...
- 【bzoj4695】最假女选手 线段树区间最值操作
题目描述 给定一个长度为 N 序列,编号从 1 到 N .要求支持下面几种操作:1.给一个区间[L,R] 加上一个数x 2.把一个区间[L,R] 里小于x 的数变成x 3.把一个区间[L,R] 里大于 ...
- HUD.2795 Billboard ( 线段树 区间最值 单点更新 单点查询 建树技巧)
HUD.2795 Billboard ( 线段树 区间最值 单点更新 单点查询 建树技巧) 题意分析 题目大意:一个h*w的公告牌,要在其上贴公告. 输入的是1*wi的w值,这些是公告的尺寸. 贴公告 ...
- 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 ...
- cf834D(dp+线段树区间最值,区间更新)
题目链接: http://codeforces.com/contest/834/problem/D 题意: 每个数字代表一种颜色, 一个区间的美丽度为其中颜色的种数, 给出一个有 n 个元素的数组, ...
- HDU 3911 Black And White(线段树区间合并+lazy操作)
开始以为是水题,结果...... 给你一些只有两种颜色的石头,0为白色,1为黑色. 然后两个操作: 1 l r 将[ l , r ]内的颜色取反 0 l r 计算[ l , r ]内最长连续黑色石头的 ...
- UVA 1400."Ray, Pass me the dishes!" -分治+线段树区间合并(常规操作+维护端点)并输出最优的区间的左右端点-(洛谷 小白逛公园 升级版)
"Ray, Pass me the dishes!" UVA - 1400 题意就是线段树区间子段最大和,线段树区间合并,但是这道题还要求输出最大和的子段的左右端点.要求字典序最小 ...
- HDU-1754I Hate It 线段树区间最值
这道题比较基本,就是用线段树维护区间最值,可以算是模板吧-.. I Hate It Time Limit: 9000/3000 MS (Java/Others) Memory Limit: 32768 ...
随机推荐
- sql语句-6-更新数据
- python 多线程笔记(6)-- 生产者/消费者模式(续)
用 threading.Event() 也可以实现生产者/消费者模式 (自己拍脑袋想出来的,无法知道其正确性,请大神告知为谢!) import threading import time import ...
- C# 远程图片下载到本地
下载方法 using System; using System.Net; using System.IO; using System.Text; namespace Common { /// < ...
- C# TTS-文本转语音
System.Speech 命名空间包含支持语音识别的类型,你可以从Visual Studio很方便的添加相关组件的引用. System.Speech相关介绍:https://msdn.microso ...
- The specified value "2019-1-2" does not conform to the required format, "yyyy-MM-dd"
问题: 在cshtml中转换的日期格式错误,前端报错:The specified value "2019-1-2" does not conform to the required ...
- Docker虚拟机172.17网段冲突,导致网络访问问题
在虚拟机中安装docker,linux ubuntu16 ,安装完公司172.17网段被docker0覆盖,导致ssh无法连接到ubuntu. 经过官网的这篇build your own bridge ...
- 带你玩转JavaScript中的隐式强制类型转换
正题开始前我想先抛出一个问题,==和===有什么区别?可能一般人会想,不就是后者除了比较值相等之外还会比较类型是否相等嘛,有什么好问的,谁不知道?!但是这样说还不够准确,两者的真正区别其实是==在比较 ...
- OrderSys---Spring 计划(第一天)
Sprint 计划会议: 目标: 1.了解需求分析书的内容 2.划分OrderSys的功能模块 3.开始制作原型 Sprint 3 Backlog细化: ID Name Est How to demo ...
- HDU 5154 Harry and Magical Computer 有向图判环
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5154 题解: 有向图判环. 1.用dfs,正在访问的节点标记为-1,已经访问过的节点标记为1,没有访 ...
- 学习c++ofstream和ifstream
定义数据流对象指针 对文件进行读写操作首先必须要定义一个数据流对象指针,数据流对象指针有三种类型,它们分别是: Ifstream:表示读取文件流,使用的时候必须包含头文件"ifstream& ...