传送门

线段树好题

支持区间加,区间取min" role="presentation" style="position: relative;">minmin和max" role="presentation" style="position: relative;">maxmax。

维护区间和,区间最大值,区间最小值。

这题可以类比另外一道线段树

维护区间最大,次大,最小,次小,和。

每次修改的时候考虑对每个量产生的影响,然后用最大最小值配合次大次小值剪枝就行了。

注意这题卡空间。

代码:

#include<bits/stdc++.h>
#define ll long long
#define N 500005
#define lc (p<<1)
#define rc (p<<1|1)
#define mid (T[p].l+T[p].r>>1)
#define inf (1<<30)
using namespace std;
inline ll read(){
    ll 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 void write(ll x){
    if(x<0)x=-x,putchar('-');
    if(x>9)write(x/10);
    putchar((x%10)^48);
}
int n,m;
ll a[N];
struct Node{int l,r;ll mx,mn,mxx,mnx,cmx,cmn;ll sum,lz;}T[N*3];
inline ll max(ll a,ll b){return a>b?a:b;}
inline ll min(ll a,ll b){return a<b?a:b;}
inline void pushup(int p){
    T[p].sum=T[lc].sum+T[rc].sum;
    T[p].mx=max(T[lc].mx,T[rc].mx);
    T[p].cmx=(T[p].mx==T[lc].mx?T[lc].cmx:0)+(T[p].mx==T[rc].mx?T[rc].cmx:0);
    T[p].mxx=max(T[p].mx==T[lc].mx?T[lc].mxx:T[lc].mx,T[p].mx==T[rc].mx?T[rc].mxx:T[rc].mx);
    T[p].mn=min(T[lc].mn,T[rc].mn);
    T[p].cmn=(T[p].mn==T[lc].mn?T[lc].cmn:0)+(T[p].mn==T[rc].mn?T[rc].cmn:0);
    T[p].mnx=min(T[p].mn==T[lc].mn?T[lc].mnx:T[lc].mn,T[p].mn==T[rc].mn?T[rc].mnx:T[rc].mn);
}
inline void pushnow_mn(int p,ll v){
    if(T[p].mn>=v)return;
    T[p].sum+=T[p].cmn*(v-T[p].mn);
    T[p].mn=v,T[p].mx=max(T[p].mx,v);
    if(T[p].mn==T[p].mx)T[p].sum=1ll*(T[p].cmn=T[p].cmx=(T[p].r-T[p].l+1))*(T[p].mx=T[p].mn=v),T[p].mxx=-inf,T[p].mnx=inf;
    else T[p].mxx=max(T[p].mxx,v);
}
inline void pushnow_mx(int p,ll v){
    if(T[p].mx<=v)return;
    T[p].sum+=T[p].cmx*(v-T[p].mx);
    T[p].mx=v,T[p].mn=min(T[p].mn,v);
    if(T[p].mn==T[p].mx)T[p].sum=1ll*(T[p].cmn=T[p].cmx=(T[p].r-T[p].l+1))*(T[p].mx=T[p].mn=v),T[p].mxx=-inf,T[p].mnx=inf;
    else T[p].mnx=min(T[p].mnx,v);
}
inline void pushnow(int p,ll v){
    T[p].lz+=v,T[p].sum+=1ll*(T[p].r-T[p].l+1)*v;
    T[p].mn+=v,T[p].mx+=v,T[p].mxx+=v,T[p].mnx+=v;
}
inline void pushdown(int p){
    if(T[p].lz)pushnow(lc,T[p].lz),pushnow(rc,T[p].lz),T[p].lz=0;
    pushnow_mn(lc,T[p].mn),pushnow_mn(rc,T[p].mn);
    pushnow_mx(lc,T[p].mx),pushnow_mx(rc,T[p].mx);
}
inline void build(int p,int l,int r){
    T[p].l=l,T[p].r=r,T[p].lz=0;
    if(l==r){
        T[p].mx=T[p].mn=T[p].sum=a[l];
        T[p].cmx=T[p].cmn=1;
        T[p].mxx=-inf,T[p].mnx=inf;
        return;
    }
    build(lc,l,mid),build(rc,mid+1,r),pushup(p);
}
inline void update(int p,int ql,int qr,ll v){
    if(ql>T[p].r||qr<T[p].l)return;
    if(ql<=T[p].l&&T[p].r<=qr){pushnow(p,v);return;}
    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 modify1(int p,int ql,int qr,ll v){
    if(ql>T[p].r||qr<T[p].l||T[p].mn>=v)return;
    if(ql<=T[p].l&&T[p].r<=qr&&T[p].mnx>v){pushnow_mn(p,v);return;}
    pushdown(p);
    if(qr<=mid)modify1(lc,ql,qr,v);
    else if(ql>mid)modify1(rc,ql,qr,v);
    else modify1(lc,ql,mid,v),modify1(rc,mid+1,qr,v);
    pushup(p);
}
inline void modify2(int p,int ql,int qr,ll v){
    if(ql>T[p].r||qr<T[p].l||T[p].mx<=v)return;
    if(ql<=T[p].l&&T[p].r<=qr&&T[p].mxx<v){pushnow_mx(p,v);return;}
    pushdown(p);
    if(qr<=mid)modify2(lc,ql,qr,v);
    else if(ql>mid)modify2(rc,ql,qr,v);
    else modify2(lc,ql,mid,v),modify2(rc,mid+1,qr,v);
    pushup(p);
}
inline ll query_sum(int p,int ql,int qr){
    if(ql>T[p].r||qr<T[p].l)return 0;
    if(ql<=T[p].l&&T[p].r<=qr)return T[p].sum;
    pushdown(p);
    if(qr<=mid)return query_sum(lc,ql,qr);
    if(ql>mid)return query_sum(rc,ql,qr);
    return query_sum(lc,ql,mid)+query_sum(rc,mid+1,qr);
}
inline ll query_max(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;
    pushdown(p);
    if(qr<=mid)return query_max(lc,ql,qr);
    if(ql>mid)return query_max(rc,ql,qr);
    return max(query_max(lc,ql,mid),query_max(rc,mid+1,qr));
}
inline ll query_min(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;
    pushdown(p);
    if(qr<=mid)return query_min(lc,ql,qr);
    if(ql>mid)return query_min(rc,ql,qr);
    return min(query_min(lc,ql,mid),query_min(rc,mid+1,qr));
}
int main(){
    n=read();
    for(int i=1;i<=n;++i)a[i]=read();
    build(1,1,n);
    m=read();
    while(m--){
        int op=read(),l=read(),r=read();
        switch(op){
            case 1:{ll v=read();update(1,l,r,v);break;}
            case 2:{ll v=read();modify1(1,l,r,v);break;}
            case 3:{ll v=read();modify2(1,l,r,v);break;}
            case 4:{write(query_sum(1,l,r)),puts("");break;}
            case 5:{write(query_max(1,l,r)),puts("");break;}
            default:{write(query_min(1,l,r)),puts("");break;}
        }
    }
    return 0;
}

2018.07.27 bzoj4695: 最假女选手(线段树)的更多相关文章

  1. 【bzoj4695】最假女选手 线段树区间最值操作

    题目描述 给定一个长度为 N 序列,编号从 1 到 N .要求支持下面几种操作:1.给一个区间[L,R] 加上一个数x 2.把一个区间[L,R] 里小于x 的数变成x 3.把一个区间[L,R] 里大于 ...

  2. BZOJ.4695.最假女选手(线段树 Segment tree Beats!)

    题目链接 区间取\(\max,\ \min\)并维护区间和是普通线段树无法处理的. 对于操作二,维护区间最小值\(mn\).最小值个数\(t\).严格次小值\(se\). 当\(mn\geq x\)时 ...

  3. BZOJ 4695 最假女选手 线段树

    题意: 给定一个长度为 N序列,编号从1 到 N.要求支持下面几种操作: 1.给一个区间[L,R] 加上一个数x  2.把一个区间[L,R] 里小于x 的数变成x  3.把一个区间[L,R] 里大于x ...

  4. BZOJ4695 最假女选手(势能线段树)

    BZOJ题目传送门 终于体会到初步掌握势能分析思想的重要性了. 一开始看题,感觉套路还是很一般啊qwq.直接在线段树上维护最大值和最小值,每次递归更新的时候,如果不能完全覆盖就暴力递归下去.挺好写的欸 ...

  5. bzoj4695 最假女选手

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4695 [题解] SegmentTree beats!(见jiry_2论文/营员交流) 考虑只 ...

  6. [BZOJ4695]最假女选手:segment tree beats!

    分析 segment tree beats!模板题. 看了gxz的博客突然发现自己写的mxbt和mnbt两个标记没用诶. 代码 #include <bits/stdc++.h> #defi ...

  7. bzoj4695 最假女选手(势能线段树/吉司机线段树)题解

    题意: 已知\(n\)个数字,进行以下操作: \(1.\)给一个区间\([L,R]\) 加上一个数\(x\) \(2.\)把一个区间\([L,R]\) 里小于\(x\) 的数变成\(x\) \(3.\ ...

  8. 2018.07.03 HDU Rikka with Phi(线段树)

    Rikka with Phi Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others) P ...

  9. 2018.08.27 [Usaco2017 Jan]Promotion Counting(线段树合并)

    描述 The cows have once again tried to form a startup company, failing to remember from past experienc ...

随机推荐

  1. springVC + logback

    为什么用logback,而不是log4j? springmvc log只输出到console,不输出到文件 Spring MVC集成slf4j-logback springMVC如何配置logback ...

  2. RocketMQ初探(五)之RocketMQ4.2.6集群部署(单Master+双Master+2m+2s+async异步复制)

    以下部署方式结合众多博友的博客,经过自己一步一步实际搭建,如有雷同,侵权行为,请见谅...其中遇到不少的坑,希望能帮到更多的人,现在很少能找到一份完整版4.2.6版本的搭建教程了,如果你有幸遇见,那么 ...

  3. Java对字符串使用MD5进行加密(亲测有效)

    转自:https://blog.csdn.net/jay314159/article/details/4918358 前言: MD5即Message-Digest Algorithm 5(信息-摘要算 ...

  4. jquery实现背景图片动态适应

    背景 在我的一个项目中用到了背景图片,发现其中有一个问题,当页面长度动态变化时,原来能占满全部内容背景的图片会变得不能占满全部背景.如下图的效果: 这是正常的,背景图片占满全屏 当页面内容变长出现了滚 ...

  5. sql server 2000能否得到一个表的最后更新日期?

    如果是SQL 2005 或 2008.运行下面的代码.就可以看到从上次启动SQL 服务以来,某个表的使用情况,包括select/update/delete/insert. SELECT * FROM ...

  6. libUpnp缓冲区溢出、拒绝服务等漏洞分析

    该漏洞存在于UPnP™设备的便携式SDK中,也叫做 libupnp.这个库是用来实现媒体播放(DLAN)或者NAT地址转换(UPnP IGD).智能手机上的应用程序可用这些功能播放媒体文件或者利用用户 ...

  7. while

    public class TestWhile { /** * 测试循环 */ public static void main(String[] args) { int a=1; while(a< ...

  8. Process子类

    创建新的进程还能够使用类的方式,可以自定义一个类,继承Process类,每次实例化这个类的时候,就等同于实例化一个进程对象,请看下面的实例: from multiprocessing import P ...

  9. Linux就业技术指导(一):简历撰写及面试筹备要领

    一,开场 二,模型 三,目标选材 3.1 什么是目标选材 简单说就是确定一个候选人是否符合某一个工作岗位要求的整个流程.这是对招聘方的一个培训,应聘方如果掌握了,就知道应该怎样正确的去应聘工作. 3. ...

  10. Baidu URL的部分参数

    [Baidu URL的部分参数] 1.Baidu Form表单如下: 2.部分参数解析 wd  查询关键字,就是你要搜索的内容. bs 上一次搜索的词或者内容: rn  搜索结果页每页显示的数目,默认 ...