2018.07.28 uoj#169. 【UR #11】元旦老人与数列(线段树)

这篇博客介绍了如何使用线段树解决一道数据结构问题,包括区间加、取最大值和求最小值的操作。作者提到在不考虑历史区间最小值的情况下,可以维护区间最小和次小值,结合标记更新来解决。文章中提供了更新后的代码实现。
摘要由CSDN通过智能技术生成

传送门
线段树好题。
维护区间加,区间取最大值,维护区间最小值,历史区间最小值。
同样先考虑不用维护历史区间最小值的情况,这个可以参考这道题的解法,维护区间最小和次小值可以解决前两个操作,然后使用历史标记的常规维护方式合并标记更新就行了。
代码:

#include<bits/stdc++.h>
#define lc (p<<1)
#define rc (p<<1|1)
#define mid (T[p].l+T[p].r>>1)
#define N 500005
#define inf 2000000030
using namespace std;
struct Node{int l,r,sn,mn,add,his,his_add,his_mn,f;}T[N<<2];
int n,m,a[N];
inline int read(){
    int ans=0,w=1;char ch=getchar();
    while(!isdigit(ch)){
  if(ch=='-')w=-1;ch=getchar();}
    while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
    return ans*w;
}
inline int min(int a,int b){
  return a<b?a:b;}
inline void pushup(int p){
    T[p].his=min(T[lc].his,T[rc].his),T[lc].f=T[rc].f=0,T[p].mn=min(T[lc].mn,T[rc].mn);
    T[p].sn=min(T[p].mn==T[lc].mn?T[lc].sn:T[lc].mn,T[p].mn==T[rc].mn?T[rc].sn:T[rc].mn);
    if(T[lc].mn==T[p].mn)T[lc].f=1;
    if(T[rc].mn==T[p].mn)T[rc].f=1;
}
inline void pushadd(int p,int v){
    T[p].his_add=min(T[p].his_add,T[p].add+=v),T[p].sn+=v;
    T[p].his=min(T[p].his,T[p].mn+=v),T[p].his_mn=min(T[p].his_mn,T[p].mn);
}
inline void pushset(int p,int v){
  if(T[p].mn>=v)return;T[p].mn=v;}
inline void pushdown(int p){
    if(T[lc].f)T[lc].his=min(T[lc].his,T[p].his_mn),T[lc].his_mn=min(T[lc].his_mn,T[p].his_mn);
    else T[lc].his=min(T[lc].his,T[lc]
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值