UOJ164 V 线段树lazytag维护历史最值

原创 2017年01月15日 20:10:16

题意:维护一列数,支持:
1.区间加A
2.区间减A,减法结束后每个位置与0取max
3.区间覆盖成A
4.询问单点当前值
5.询问单点历史最值

线段树lazytag维护历史最值,要记录四个数组,注意转移以及初始条件。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long LL;
const int maxn=10000010;
const LL INF=1e18;
int n,m;
struct Tree{
    LL add,addmax,r,rmax;
}tree[maxn<<2],tmp;
int qx;
int ql,qr;
int type;
LL s[maxn];
void build(int o,int l,int r){
    if(l==r){
        tree[o]=(Tree){0,0,-INF,-INF};
        return;
    }
    int lc=o<<1,rc=o<<1|1,mid=(l+r)>>1;
    build(lc,l,mid);
    build(rc,mid+1,r);
}
Tree update(Tree u,Tree v){
    return (Tree){
        max(u.add+v.add,-INF),max(u.addmax,u.add+v.addmax),max(u.r+v.add,v.r),max(max(u.rmax,v.rmax),u.r+v.addmax)
    };
}
void pushdown(int o){
    tree[o<<1]=update(tree[o<<1],tree[o]);
    tree[o<<1|1]=update(tree[o<<1|1],tree[o]);
    tree[o]=(Tree){0,-INF,0,-INF};
}
void change(int o,int l,int r){
    if(ql<=l && qr>=r){
        tree[o]=update(tree[o],tmp);
        return;
    }
    pushdown(o);
    int lc=o<<1,rc=o<<1|1,mid=(l+r)>>1;
    if(ql<=mid) change(lc,l,mid);
    if(qr>mid) change(rc,mid+1,r);
}
void query(int o,int l,int r){
    if(l==r){
        if(type==4) printf("%lld\n",max(tree[o].add+s[qx],tree[o].r));
        if(type==5) printf("%lld\n",max(tree[o].addmax+s[qx],tree[o].rmax));
        return;
    }
    pushdown(o);
    int lc=o<<1,rc=o<<1|1,mid=(l+r)>>1;
    if(qx<=mid) query(lc,l,mid);
    else query(rc,mid+1,r);
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%lld",&s[i]);
    build(1,1,n);
    while(m--){
        scanf("%d",&type);
        int x;
        if(type<=3){
            scanf("%d%d",&ql,&qr);
            scanf("%d",&x);
            if(type==1)tmp=(Tree){x,x,-INF,-INF};
            if(type==2)tmp=(Tree){-x,-x,0,0};
            if(type==3)tmp=(Tree){-INF,-INF,x,x};
            change(1,1,n);
        }else{
            scanf("%d",&qx);
            query(1,1,n);
        }
    }
    return 0;
}

^_^

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

HDU 2795 放模板 (线段树_维护最大值,好题)

题意:有个公告板,大小为h*w,要贴n张公告,每个公告的长度是k,高度固定为1,公告放的要尽可能靠上并尽可能靠左,每给出一张公告,要求这个公告在满足要求的情况下放在了第几层。 Sample Inp...

hdu1754线段树维护区间最大值

#include #include using namespace std; #define MAXN 200005 int N,M; int grade[MAXN]; struct n...

[历史最值问题] UOJ #164 【清华集训2015】V

详见吉丽的集训队论文吧我们发现修改操作可以变为这样一个形式S:x=max(x+A,B)S:x=max(x+A,B) 这个标记是可以合并的 就可以求当前值了 现在还要历史最值 我们就再加一个标记SS...

poj2823Sliding Window【线段树维护滚动区间最值】

Description An array of size n ≤ 10 6 is given to you. There is a sliding window of size k which...

HDOJ-2795 Billboard [线段树][单点更新+单点查询+维护区间最值]

8s时限 单点更新+单点查询(要用区间信息来找到那个点) 注意:对于维护区间最值的, 附加域直接当主域用, 因为叶节点的最值就是那个点的值 思路: 1/ 维护区间最左的还未满w的点, ...
  • tclh123
  • tclh123
  • 2012年08月12日 01:00
  • 416

hdu 4902 Nice boat(线段树区间更新lazytag·单点更新)

题目:http://acm.hdu.edu.cn/showproblem.php?pid=4902 Nice boat Time Limit: 30000/15000 MS (Java/O...

BZOJ 3064 Tyvj 1518 CPU监控 线段树维护历史最大值

题目大意:给出一个数列要求支持:查询区间最大值,查询区间历史最大值,区间加,区间修改...
  • YihAN_Z
  • YihAN_Z
  • 2017年06月16日 09:31
  • 212

hdu 1754 I Hate It(线段树之 单点更新+区间最值)

I Hate It                                                                             Time Limit: 90...

线段树 区间更新 区间求和以及最值

#include #include #include #include #include #include #define MAXN 100010 #define inf 0x3f3f3f...

Codeforces 272C Dima and Staircase 线段树区间覆盖,最值查询

传送门:点击打开链接 C. Dima and Staircase time limit per test 2 seconds memory limit per test 256 megaby...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:UOJ164 V 线段树lazytag维护历史最值
举报原因:
原因补充:

(最多只允许输入30个字)