传送门

线段树好题。

维护区间取两种最值,区间加,求区间两种历史最值,区间最小值。

自己的写法调了一个晚上+一个上午+一个下午+一个晚上并没有调出来,90" role="presentation" style="position: relative;">9090分弃疗。

于是我开始学习新的写法。

也就是封装再封装。

然后发现自己的方法的确有不严谨的地方,但并不好改,于是写了一个凌晨参考了xuyixuan" role="presentation" style="position: relative;">xuyixuanxuyixuan神犇的写法调过了这题。

实际上就是我们对区间标记,区间最大值,区间最小值分别用三类结构体表示(顺便来个重载运算符)。然后就到了本蒟蒻出锅的地方:区间标记需要维护三类数的(我只维护了两类),最大值的,最小值的,既不是最大值也不是最小值的(这一项我并没有维护然后gg" role="presentation" style="position: relative;">gggg),然后分个类什么的再结合下面几道经典线段树应该就能做出来这道题了。

uoj#169. 【UR #11】元旦老人与数列

uoj#164. 【清华集训2015】V

bzoj3064: Tyvj 1518 CPU监控

bzoj4695: 最假女选手

hdu5306Gorgeous Sequence

代码:

#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 2e9
using namespace std;
inline int max(int a,int b){return a>b?a:b;}
inline int min(int a,int b){return a<b?a:b;}
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;
}
int n,m,a[N];
struct tag{int add,addmx,addmn;};
struct Max{int his,mx,sx;}mxtmp;
struct Min{int his,mn,sn;}mntmp;
struct Node{int l,r;Max mx;Min mn;tag Amax,Bmid,Cmin;}T[N<<2];
inline tag operator+(tag a,tag b){return (tag){a.add+b.add,max(a.addmx,b.addmx+a.add),min(a.addmn,b.addmn+a.add)};}
inline tag operator+(tag a,int b){return (tag){a.add+b,max(a.addmx,a.add+b),min(a.addmn,a.add+b)};}
inline Max operator+(Max a,Max b){return (Max){max(a.his,b.his),max(a.mx,b.mx),a.mx==b.mx?max(a.sx,b.sx):(a.mx<b.mx?max(a.mx,b.sx):max(a.sx,b.mx))};}
inline Min operator+(Min a,Min b){return (Min){min(a.his,b.his),min(a.mn,b.mn),a.mn==b.mn?min(a.sn,b.sn):(a.mn>b.mn?min(a.mn,b.sn):min(a.sn,b.mn))};}
inline void pushup(int p){T[p].mn=T[lc].mn+T[rc].mn,T[p].mx=T[lc].mx+T[rc].mx;}
inline void build(int p,int l,int r){
    T[p].l=l,T[p].r=r,T[p].Amax=T[p].Bmid=T[p].Cmin=(tag){0,0,0};
    if(l==r){T[p].mn=(Min){a[l],a[l],inf},T[p].mx=(Max){a[l],a[l],-inf};return;}
    build(lc,l,mid),build(rc,mid+1,r),pushup(p);
}
inline void pushadd(int p,int v){
    T[p].mx.mx+=v,T[p].mn.mn+=v;
    if(T[p].mx.sx!=-inf)T[p].mx.sx+=v;
    if(T[p].mn.sn!=inf)T[p].mn.sn+=v;
    T[p].mx.his=max(T[p].mx.his,T[p].mx.mx),T[p].mn.his=min(T[p].mn.his,T[p].mn.mn);
    T[p].Amax=T[p].Amax+v,T[p].Bmid=T[p].Bmid+v,T[p].Cmin=T[p].Cmin+v;
}
inline void pushAmax(int p,tag v){
    T[p].mx.his=max(T[p].mx.his,v.addmx+T[p].mx.mx);
    if(mxtmp.mx==mntmp.sn)T[p].mn.sn+=v.add;
    T[p].mx.mx+=v.add;
    T[p].Amax=T[p].Amax+v;
}
inline void pushBmid(int p,tag v){
    if(mxtmp.mx!=mntmp.sn&&mntmp.sn!=inf)T[p].mn.sn+=v.add;
    if(mntmp.mn!=mxtmp.sx&&mxtmp.sx!=-inf)T[p].mx.sx+=v.add;
    T[p].Bmid=T[p].Bmid+v;
}
inline void pushCmin(int p,tag v){
    T[p].mn.his=min(T[p].mn.his,v.addmn+T[p].mn.mn);
    if(mntmp.mn==mxtmp.sx)T[p].mx.sx+=v.add;
    T[p].mn.mn+=v.add;
    T[p].Cmin=T[p].Cmin+v;
}
inline void pushdown(int p){
    int chemn=min(T[lc].mn.mn,T[rc].mn.mn),chemx=max(T[lc].mx.mx,T[rc].mx.mx);
    mxtmp=T[lc].mx,mntmp=T[lc].mn;
    if(T[lc].mx.mx==chemx)pushAmax(lc,T[p].Amax);
    else if(T[lc].mx.mx==chemn)pushAmax(lc,T[p].Cmin);
    else pushAmax(lc,T[p].Bmid);
    pushBmid(lc,T[p].Bmid);
    if(T[lc].mn.mn==chemn)pushCmin(lc,T[p].Cmin);
    else if(T[lc].mn.mn==chemx)pushCmin(lc,T[p].Amax);
    else pushCmin(lc,T[p].Bmid);
    mxtmp=T[rc].mx,mntmp=T[rc].mn;
    if(T[rc].mx.mx==chemx)pushAmax(rc,T[p].Amax);
    else if(T[rc].mx.mx==chemn)pushAmax(rc,T[p].Cmin);
    else pushAmax(rc,T[p].Bmid);
    pushBmid(rc,T[p].Bmid);
    if(T[rc].mn.mn==chemn)pushCmin(rc,T[p].Cmin);
    else if(T[rc].mn.mn==chemx)pushCmin(rc,T[p].Amax);
    else pushCmin(rc,T[p].Bmid);
    T[p].Amax=T[p].Bmid=T[p].Cmin=(tag){0,0,0};
}
inline void update(int p,int ql,int qr,int v){
    if(ql>T[p].r||qr<T[p].l)return;
    if(ql<=T[p].l&&T[p].r<=qr)return pushadd(p,v);
    pushdown(p);
    if(qr<=mid)update(lc,ql,qr,v);
    else if(ql>mid)update(rc,ql,qr,v);
    else update(lc,ql,mid,v),update(rc,mid+1,qr,v);
    pushup(p);
}
inline void updmax(int p,int ql,int qr,int v){
    if(ql>T[p].r||qr<T[p].l||T[p].mx.mx<=v)return;
    if(ql<=T[p].l&&T[p].r<=qr&&T[p].mx.sx<v){
        mxtmp=T[p].mx,mntmp=T[p].mn;
        if(T[p].mx.mx==T[p].mn.mn)pushCmin(p,(tag){v-T[p].mx.mx,v-T[p].mx.mx,0});
        return pushAmax(p,(tag){v-T[p].mx.mx,v-T[p].mx.mx,0});
    }
    pushdown(p);
    if(qr<=mid)updmax(lc,ql,qr,v);
    else if(ql>mid)updmax(rc,ql,qr,v);
    else updmax(lc,ql,mid,v),updmax(rc,mid+1,qr,v);
    pushup(p);
}
inline void updmin(int p,int ql,int qr,int v){
    if(ql>T[p].r||qr<T[p].l||T[p].mn.mn>=v)return;
    if(ql<=T[p].l&&T[p].r<=qr&&T[p].mn.sn>v){
        mxtmp=T[p].mx,mntmp=T[p].mn;
        if(T[p].mx.mx==T[p].mn.mn)pushAmax(p,(tag){v-T[p].mn.mn,0,v-T[p].mn.mn});
        return pushCmin(p,(tag){v-T[p].mn.mn,0,v-T[p].mn.mn});
    }
    pushdown(p);
    if(qr<=mid)updmin(lc,ql,qr,v);
    else if(ql>mid)updmin(rc,ql,qr,v);
    else updmin(lc,ql,mid,v),updmin(rc,mid+1,qr,v);
    pushup(p);
}
inline int query(int p,int ql,int qr){
    if(ql>T[p].r||qr<T[p].l)return inf;
    if(ql<=T[p].l&&T[p].r<=qr)return T[p].mn.mn;
    pushdown(p);
    if(qr<=mid)return query(lc,ql,qr);
    if(ql>mid)return query(rc,ql,qr);
    return min(query(lc,ql,mid),query(rc,mid+1,qr));
}
inline int querymn(int p,int ql,int qr){
    if(ql>T[p].r||qr<T[p].l)return inf;
    if(ql<=T[p].l&&T[p].r<=qr)return T[p].mn.his;
    pushdown(p);
    if(qr<=mid)return querymn(lc,ql,qr);
    if(ql>mid)return querymn(rc,ql,qr);
    return min(querymn(lc,ql,mid),querymn(rc,mid+1,qr));
}
inline int querymx(int p,int ql,int qr){
    if(ql>T[p].r||qr<T[p].l)return -inf;
    if(ql<=T[p].l&&T[p].r<=qr)return T[p].mx.his;
    pushdown(p);
    if(qr<=mid)return querymx(lc,ql,qr);
    if(ql>mid)return querymx(rc,ql,qr);
    return max(querymx(lc,ql,mid),querymx(rc,mid+1,qr));
}
int main(){
    n=read(),m=read();
    for(int i=1;i<=n;++i)a[i]=read();
    build(1,1,n);
    while(m--){
        int op=read(),l=read(),r=read();
        if(op==1){int v=read();update(1,l,r,v);}
        if(op==2){int v=read();updmin(1,l,r,v);}
        if(op==3)printf("%d\n",query(1,l,r));
        if(op==4)printf("%d\n",querymn(1,l,r));
        if(op==5){int v=read();updmax(1,l,r,v);}
        if(op==6)printf("%d\n",querymx(1,l,r));
    }
    return 0;
}

2018.07.29~30 uoj#170. Picks loves segment tree VIII(线段树)的更多相关文章

  1. picks loves segment tree I

    picks loves segment tree I 题目背景 来源: \(\text {2018 WC Segment Tree Beats}\) 原作者: \(\text {C_SUNSHINE} ...

  2. hdu 5274 Dylans loves tree(LCA + 线段树)

    Dylans loves tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

  3. UOJ#77. A+B Problem [可持久化线段树优化建边 最小割]

    UOJ#77. A+B Problem 题意:自己看 接触过线段树优化建图后思路不难想,细节要处理好 乱建图无果后想到最小割 白色和黑色只能选一个,割掉一个就行了 之前选白色必须额外割掉一个p[i], ...

  4. Codeforces 446C —— DZY Loves Fibonacci Numbers(线段树)

    题目:DZY Loves Fibonacci Numbers 题意比較简单,不解释了. 尽管官方的题解也是用线段树,但还利用了二次剩余. 可是我没有想到二次剩余,然后写了个感觉非常复杂度的线段树,还是 ...

  5. ACM/ICPC 2018亚洲区预选赛北京赛站网络赛 D 80 Days (线段树查询最小值)

    题目4 : 80 Days 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 80 Days is an interesting game based on Jules Ve ...

  6. 【2018.07.29】(深度优先搜索/回溯)学习DFS算法小记

    参考网站:https://blog.csdn.net/ldx19980108/article/details/76324307 这个网站里有动态图给我们体现BFS和DFS的区别:https://www ...

  7. 2018.07.30 cogs2632. [HZOI 2016] 数列操作d(线段树)

    传送门 线段树基本操作 区间加等差数列,维护区间和. 对于每个区间维护等差数列首项和公差,易证这两个东西都是可合并的,然后使用小学奥数的知识就可以切掉这题. 代码: #include<bits/ ...

  8. 2018.07.01 BZOJ3295: [Cqoi2011]动态逆序对(带修主席树)

    3295: [Cqoi2011]动态逆序对 **Time Limit: 10 Sec Memory Limit: 128 MB Description 对于序列A,它的逆序对数定义为满足i<j& ...

  9. 2018.07.01洛谷P2617 Dynamic Rankings(带修主席树)

    P2617 Dynamic Rankings 题目描述 给定一个含有n个数的序列a[1],a[2],a[3]--a[n],程序必须回答这样的询问:对于给定的i,j,k,在a[i],a[i+1],a[i ...

随机推荐

  1. 关于RabbitMQ以及RabbitMQ和Spring的整合

    转自:https://www.cnblogs.com/s648667069/p/6401463.html 基本概念 RabbitMQ是流行的开源消息队列系统,用erlang语言开发.RabbitMQ是 ...

  2. mysql数据库复制

    核心命令是 myssqldump mysqldump --host=host1 --opt sourceDb| mysql --host=host2 -C targetDb 详情参考: MySQL数据 ...

  3. ABAP-ALV详解

    OO ALV: https://www.cnblogs.com/jiangzhengjun/p/4291373.html https://www.cnblogs.com/jiangzhengjun/p ...

  4. python 安装mysqldb组件

    只能源码安装 源码下载: http://sourceforge.net/projects/mysql-python/files/mysql-python/1.2.3/ http://sourcefor ...

  5. ArcGIS案例学习笔记3_1

    ArcGIS案例学习笔记3_1 联系方式:谢老师,135_4855_4328,xiexiaokui#139.com 时间:第三天上午 内容1:ArcGIS 平台介绍 体系结构 Arcgis for d ...

  6. ArcGIS案例学习笔记2_2

    ArcGIS案例学习笔记2_2 联系方式:谢老师,135_4855_4328,xiexiaokui#qq.com 时间:第二天下午 2018年8月12日 案例1:模型构建器,山顶点提取 背景:数据量大 ...

  7. spring ioc xml配置

    一个完整的spring xml配置:是把action,service,dao以及其它的资源性配置(如basedao)和公共性配置(如连接数据库)配置在resource.xml中,这样就有四个xml配置 ...

  8. KNN识别手写数字

    一.问题描述 手写数字被存储在EXCEL表格中,行表示一个数字的标签和该数字的像素值,有多少行就有多少个样本. 一共42000个样本 二.KNN KNN最邻近规则,主要应用领域是对未知事物的识别,即判 ...

  9. 【转】Android Shape绘制虚线在手机端查看是实线的问题

    Android share绘制虚线在手机上显示实线问题 给控件添加Drawableleft等图片后,单独给图片设置动画效果,参考文章: http://blog.csdn.net/langzxz/art ...

  10. Java动态代理的实现方法

    AOP的拦截功能是由java中的动态代理来实现的.说白了,就是在目标类的基础上增加切面逻辑,生成增强的目标类(该切面逻辑或者在目标类函数执行之前,或者目标类函数执行之后,或者在目标类函数抛出异常时候执 ...