HUD3954-Level up(线段树技巧)

本文介绍了一道关于线段树懒惰更新的题目,通过详细的AC代码解析了如何解决该问题。针对N个初始等级为1的英雄,在面对M波怪物攻击时,如何通过懒惰更新的方式高效地计算经验值最高的英雄等级。

题目大意:

有N个英雄,初始为1级,0经验。有M波怪物,每波怪物选择区间[l,r]的英雄去打,打死每波怪物的英雄会获得k(等级)*ei的经验,现在给出升到每个等级所需要的经验,和每波怪物派出的英雄,每次询问一个区间内经验值最高的值。


思路:

一道线段树区间更新变形题,容易想到每次更新对每个子区间的改变是不同的,但是,对答案的英雄却是唯一的,假设一个区间的最大等级为lv,那么更新当v前区间时,如果没有英雄升级,区间的答案满足,ans=ans+ei*lv,所以可以使用懒惰更新,如果有英雄升级,那么应当暴力更新到底,更新一次的复杂度为logn。k<=10,那么每个点修改的次数不超过10,所以整体复杂度为k*nlogn,是满足要求的。


AC代码:

#include <stdio.h>
#include <algorithm>

using namespace std;
typedef long long ll;
const ll mod = 1e9 + 7;
const ll INF = 1e15;
const ll maxn = 1e5 + 10;
struct node {
    ll lv;
    ll min_dif;//当前区间升级所需要的最小ei
    ll max_exp;
    ll flag;
} t[8 * maxn];
ll n, k, m;
ll needexp[maxn];

void pushup(ll root) {
    t[root].min_dif = min(t[root << 1].min_dif, t[root << 1 | 1].min_dif);
    t[root].max_exp = max(t[root << 1].max_exp, t[root << 1 | 1].max_exp);
    t[root].lv = max(t[root << 1].lv, t[root << 1 | 1].lv);
}

void build(ll l, ll r, ll root) {
    t[root].max_exp = 0;
    t[root].min_dif = 0;
    t[root].flag = 0;
    t[root].lv = 0;
    if (l == r) {
        t[root].lv = 1;
        t[root].max_exp = 0;
        t[root].min_dif = needexp[2];
        return;
    }
    ll mid = (l + r) / 2;
    build(l, mid, root << 1);
    build(mid + 1, r, root << 1 | 1);
    pushup(root);
}

void pushdown(ll root) {
    t[root << 1].min_dif -= t[root].flag;
    t[root << 1].max_exp += t[root].flag * t[root << 1].lv;
    t[root << 1].flag += t[root].flag;
    t[root << 1 | 1].min_dif -= t[root].flag;
    t[root << 1 | 1].max_exp += t[root].flag * t[root << 1 | 1].lv;
    t[root << 1 | 1].flag += t[root].flag;
    t[root].flag = 0;
}

void upans(ll l, ll r, ll root) {//更新到根,也要使用懒惰更新
    if (l == r) {
        while (t[root].max_exp >= needexp[t[root ].lv + 1]) t[root].lv++;
        t[root].min_dif = (needexp[t[root].lv + 1] - t[root].max_exp) / t[root].lv +
                          ((needexp[t[root].lv + 1] - t[root].max_exp) % t[root].lv == 0 ? 0 : 1);
        return;
    }
    pushdown(root);
    ll mid = (l + r) / 2;
    if (t[root << 1].min_dif <= 0) upans(l, mid, root << 1);
    if (t[root << 1 | 1].min_dif <= 0) upans(mid + 1, r, root << 1 | 1);
    pushup(root);
}

void update(ll l, ll r, ll nl, ll nr, ll root, ll val) {
    if (l == nl && r == nr) {
        t[root].min_dif -= val;
        t[root].flag += val;
        t[root].max_exp += val * t[root].lv;
        if (t[root].min_dif <= 0) upans(l, r, root);
        return;
    }
    pushdown(root);
    ll mid = (l + r) / 2;
    if (nr <= mid) update(l, mid, nl, nr, root << 1, val);
    else if (nl > mid) update(mid + 1, r, nl, nr, root << 1 | 1, val);
    else update(l, mid, nl, mid, root << 1, val), update(mid + 1, r, mid + 1, nr, root << 1 | 1, val);
    pushup(root);
}

ll query(ll l, ll r, ll nl, ll nr, ll root) {
    if (l == nl && r == nr)
        return t[root].max_exp;
    pushdown(root);
    ll mid = (l + r) / 2;
    if (nr <= mid) return query(l, mid, nl, nr, root << 1);
    else if (nl > mid) return query(mid + 1, r, nl, nr, root << 1 | 1);
    else return max(query(l, mid, nl, mid, root << 1), query(mid + 1, r,mid + 1, nr, root << 1 | 1));
}

int main() {
    ll tcase;
    scanf("%lld", &tcase);
    for (int s = 1; s <= tcase; s++) {
        scanf("%lld%lld%lld", &n, &k, &m);
        for (int i = 2; i <= k; i++) {
            scanf("%lld", &needexp[i]);
        }
        needexp[k + 1] = INF;
        build(1, n, 1);
        printf("Case %d:\n", s);
        for(int i = 0; i < m; i++) {
            char str[10];
            scanf("%s", str);
            if (str[0] == 'W') {
                ll l, r, ei;
                scanf("%lld%lld%lld", &l, &r, &ei);
                update(1, n, l, r, 1, ei);
            }else {
                ll l, r;
                scanf("%lld%lld", &l, &r);
                printf("%lld\n", query(1, n, l, r, 1));
            }
        }
        printf("\n");
    }
    return 0;
}
### AR-HUD 和 P-HUD 的区别 增强现实抬头显示器 (AR-HUD) 和投影式抬头显示器 (P-HUD) 是两种不同类型的汽车平视显示技术。两者的主要差异在于工作原理和技术实现方式。 #### 技术原理 AR-HUD 使用先进的光学技术和传感器融合,能够将虚拟图像无缝叠加到驾驶员的真实视野中[^1]。这种特性使得导航指示、警告信息和其他驾驶辅助数据可以精确地投射在实际道路位置上,增强了用户体验的真实性。 相比之下,P-HUD 主要依赖于简单的反射镜面或波导结构来放大并投射来自仪表板的小屏幕上的影像至挡风玻璃前部区域[^2]。因此,P-HUD 提供的信息通常固定在一个特定的位置,并不随外部环境变化而调整其相对位置。 ```python # Python code demonstrating basic difference between AR-HUD and P-HUD projection methods. class HUD: def __init__(self, type): self.type = type def project(self): if self.type == "AR": print("Projecting information directly onto real-world objects.") elif self.type == "P": print("Reflecting images from an internal display.") ar_hud = HUD("AR") p_hud = HUD("P") print("AR-HUD:") ar_hud.project() print("\nP-HUD:") p_hud.project() ``` #### 应用场景 对于 **AR-HUD** 而言,在复杂路况下提供更直观的道路指引特别有用;例如,在城市环境中帮助司机识别转弯方向或是避开障碍物时显得尤为重要。此外,当车辆配备高级驾驶辅助系统(ADAS)功能时,如自适应巡航控制ACC、车道保持辅助LKA等功能集成入其中,则能进一步提升安全性与便利性。 另一方面,尽管 **P-HUD** 不具备同样的交互性和沉浸感,但在某些情况下仍然具有优势——比如成本较低廉以及安装简便等特点使其成为入门级车型的理想选择。而且由于其实现较为简单可靠,在恶劣天气条件下也能稳定运行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值