HLG 1524 最大 (离散化线段树)

本博客探讨了一个操作序列问题,其中包含修改区间值和查询区间内相同数的连续和最大值。通过实现线段树数据结构,有效地处理了输入的操作并返回相应的结果。

链接: http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1524


Description

给包含n个数的初始序列,A[1], A[2], ..., A[n]。
给q多个操作,操作如下:
1 a b v, 把[a, b] 的值改为v,即A[a] = A[a+1] = ... = A[b] = v。
2 a b, 查询[a, b] 之间的相同数的连续和最大值。

在[a, b]区间内,相同数的连续和最大值就是Sum(A[i], A[i+1], A[j]), a <= i <= j <= b,并且A[i] = A[i+1] = A[i+2] = A[i+3] = ... = A[j]。


Input

有多组测试数据,不超过5组测试数据。
对于每组测试数据,第一个为 n (n<=10^5),第二行为n个数,每个数的范围[0, 1000]。
第三行为 q (q<=10^5),表示查询的次数。
接下来有q个操作,格式如下:
1 a b v, 把[a, b] 的值改为v,即A[a] = A[a+1] = ... = A[b] = v。
2 a b, 查询[a, b] 之间的相同数的连续和最大值。
其中 1 <= a <= b <=n,0 <= v <= 1000.

Output
每组测试数据先输出一行"Case id:",id从1开始计数。
对于每个查询,输出一行,包含一个整数,为相同数的连续和最大值。

Sample Input

5
2 2 1 2 3
3
2 1 4
1 1 3 2
2 1 5
7
120 985 727 979 68 558 732
4
1 2 5 627
2 2 7
2 4 5
1 5 7 571

Sample Output

Case 1:
4
8
Case 2:
2508
1254


代码如下: (这代码当时把我弄疯了)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <limits.h>
#include <algorithm>
#define maxn 100005
#define RST(N)memset(N, 0, sizeof(N))
using namespace std;

int max(int a, int b) { return a > b ? a : b; }
int min(int a, int b) { return a < b ? a : b; }

int lva[maxn<<4];        // 最左面的值
int lnu[maxn<<4];        // 最左面的数的个数
int rva[maxn<<4];        // 最右面的值
int rnu[maxn<<4];        // 最右面的数的个数
int mva[maxn<<4];        // 区间最大连续值
int add[maxn<<4];        // 延迟标记
int v[maxn], re[100005];

void creat(int l, int r, int rt)
{
    add[rt] = -1;
    if(l == r) {
        lva[rt] = rva[rt] = v[l];
        lnu[rt] = rnu[rt] = 1;
        mva[rt] = v[l];
        return;
    }
    int m = (l+r) >> 1;
    creat(l, m, rt<<1);
    creat(m+1, r, rt<<1|1);
    lva[rt] = lva[rt<<1];
    lnu[rt] = lnu[rt<<1];
    rva[rt] = rva[rt<<1|1];
    rnu[rt] = rnu[rt<<1|1];
    if(lva[rt<<1]==lva[rt<<1|1] && lnu[rt<<1]==(m-l+1)) lnu[rt] += lnu[rt<<1|1];
    if(rva[rt<<1]==rva[rt<<1|1] && rnu[rt<<1|1]==r-m) rnu[rt] += rnu[rt<<1];
    mva[rt] = max(mva[rt<<1], mva[rt<<1|1]);
    if(rva[rt<<1] == lva[rt<<1|1]) {
        mva[rt] = max(mva[rt], rva[rt<<1]*rnu[rt<<1]+lva[rt<<1|1]*lnu[rt<<1|1]);
    }
}

void update(int L, int R, int c, int l, int r, int rt)
{
    if(L <= l && r <= R) {
        add[rt] = c;
        lva[rt] = rva[rt] = c;
        lnu[rt] = rnu[rt] = r-l+1;
        mva[rt] = c*(r-l+1);
        return;
    }
    int m = (l+r) >> 1;
    if(add[rt] != -1) {
        add[rt<<1] = add[rt<<1|1] = add[rt];
        lva[rt<<1] = rva[rt<<1] = lva[rt<<1|1] = rva[rt<<1|1] = add[rt];
        lnu[rt<<1] = rnu[rt<<1] = m-l+1;
        lnu[rt<<1|1] = rnu[rt<<1|1] = r - m;
        mva[rt<<1] = (m-l+1) * add[rt];
        mva[rt<<1|1] = (r-m) * add[rt];
        add[rt] = -1;
    }
    if(L <= m) update(L, R, c, l, m, rt<<1);
    if(R > m) update(L, R, c, m+1, r, rt<<1|1);
    lva[rt] = lva[rt<<1];
    lnu[rt] = lnu[rt<<1];
    rva[rt] = rva[rt<<1|1];
    rnu[rt] = rnu[rt<<1|1];
    if(lva[rt<<1] == lva[rt<<1|1] && lnu[rt<<1] == (m-l+1)) lnu[rt] += lnu[rt<<1|1];
    if(rva[rt<<1] == rva[rt<<1|1]&& rnu[rt<<1|1] == r-m) rnu[rt] += rnu[rt<<1];
    mva[rt] = max(mva[rt<<1], mva[rt<<1|1]);
    if(rva[rt<<1] == lva[rt<<1|1]) {
        mva[rt] = max(mva[rt], rva[rt<<1]*rnu[rt<<1]+lva[rt<<1|1]*lnu[rt<<1|1]);
    }
}

int query(int L, int R, int l, int r, int rt)
{
    if(L <= l && r <= R) return mva[rt];
    int m = (l+r) >> 1;
    if(add[rt] != -1) {
        add[rt<<1] = add[rt<<1|1] = add[rt];
        lva[rt<<1] = rva[rt<<1] = lva[rt<<1|1] = rva[rt<<1|1] = add[rt];
        lnu[rt<<1] = rnu[rt<<1] = m-l+1;
        lnu[rt<<1|1] = rnu[rt<<1|1] = r - m;
        mva[rt<<1] = (m-l+1) * add[rt];
        mva[rt<<1|1] = (r-m) * add[rt];
        add[rt] = -1;
    }
    if(R <= m) return query(L, R, l, m, rt<<1);
    else if(L > m) return query(L, R, m+1, r, rt<<1|1);
    else {
        int res = 0;
        if(rva[rt<<1] == lva[rt<<1|1])
            res = (min(rnu[rt<<1], m-L+1) + min(lnu[rt<<1|1], R-m)) * rva[rt<<1];
        return max(res, max(query(L, m, l, m, rt<<1), query(m+1, R, m+1, r, rt<<1|1)));
    }
}

int n, a, b, c, m, op, cas = 1, top = 0, tot;

void Init()
{
    for(int i=1; i<=n; i++) scanf("%d", &v[i]);
    creat(1, n, 1);
    scanf("%d", &m);
    tot = 0;
}

int main()
{
    while(~scanf("%d", &n)) {
        Init();
        printf("Case %d:\n", cas++);
        while(m--) {
            scanf("%d", &op);
            if(op == 1) {
                scanf("%d %d %d", &a, &b, &c);
                update(a, b, c, 1, n, 1);
            }else {
                scanf("%d %d", &a, &b);
                printf("%d\n", query(a, b, 1, n, 1));
            }
        }
    }
    return 0;
}



YUV颜色空间与HLG(Hybrid Log-Gamma)高动态范围技术在视频处理中具有一定的协同作用。YUV是一种将图像或视频信号分解为亮度(Y)和色度(U、V)分量的颜色空间。这种分离有助于在传输和压缩过程中优化亮度和色度信息的处理,因为人眼对亮度变化的敏感度高于对色度变化的敏感度。因此,YUV格式被广泛应用于视频编码和广播系统中,如H.264、HEVC等标准[^1]。 HLG是一种高动态范围(HDR)技术,旨在提供更宽的亮度范围,从而增强图像的对比度和细节表现力。与传统的SDR(Standard Dynamic Range)相比,HLG能够呈现更真实的亮部和暗部细节,使图像看起来更加生动和自然。HLG技术通过使用一种特殊的伽玛曲线(Log-Gamma),能够在不增加额外元数据的情况下实现HDR效果,这使得它特别适合于实时广播和视频传输[^2]。 在实际应用中,YUV颜色空间与HLG技术可以结合使用以提高视频的质量。例如,在HDR视频编码过程中,视频信号通常首先被转换为YUV颜色空间,其中亮度分量(Y)可以应用HLG技术来扩展动态范围,而色度分量(U、V)则可以根据需要进行适当的处理和压缩。这种方法不仅能够保持视频的高质量,还能有效地减少数据传输所需的带宽[^1]。 此外,由于HLG技术不需要额外的元数据,它与现有的视频传输和接收设备兼容性更好。这意味着,在使用YUV颜色空间进行视频处理时,通过引入HLG技术,可以在不显著改变现有基础设施的情况下实现HDR视频的制作和播放。 综上所述,YUV颜色空间与HLG技术在视频处理中的结合,不仅能够提升视频的视觉效果,还能够适应当前视频传输和接收设备的要求,为用户提供更加优质的观看体验。 ```python # 示例代码:假设我们有一个函数用于转换视频信号到YUV颜色空间并应用HLG技术 def convert_to_YUV_and_apply_HLG(video_signal): # 转换视频信号到YUV颜色空间 yuv_video = convert_to_YUV(video_signal) # 应用HLG技术到亮度分量 hlg_yuv_video = apply_HLG(yuv_video['Y']) # 合并处理后的亮度分量与未处理的色度分量 final_video = merge_YUV(hlg_yuv_video, yuv_video['U'], yuv_video['V']) return final_video # 假设的转换函数 def convert_to_YUV(signal): # 实现RGB到YUV转换逻辑 pass # 假设的应用HLG函数 def apply_HLG(y_component): # 实现HLG技术到亮度分量 pass # 假设的合并YUV分量函数 def merge_YUV(y, u, v): # 合并YUV分量形成最终视频 pass ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值