题意:

  给定一个长度为 N序列,编号从1 到 N。要求支持下面几种操作:

  1.给一个区间[L,R] 加上一个数x 
  2.把一个区间[L,R] 里小于x 的数变成x 
  3.把一个区间[L,R] 里大于x 的数变成x 
  4.求区间[L,R] 的和
  5.求区间[L,R] 的最大值
  6.求区间[L,R] 的最小值
 

分析:

  你听说过Segment Tree Beats么?

  快去看一看吧。这题居然才只有六个操作,真的是重口难调啊。

  思想还是不难的,这里就不粘课件了。

  由于这题拥有着比较玄学的空间限制和比较玄学的数据范围,所以可能需要试探很多遍才能不MLE。

  (如果你是指针线段树我也没啥可说的)

  代码是我修改抄袭一位大神的,予以美化(好像更难读了),以便于非指针用户食用。

代码:

 #include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=3.7e5+,inf=1e9;
struct node{
int l,r,ls,rs,mnc,mxc;//标号为1代表最值
ll mn1,mn2,mx1,mx2;//,为2代表次值
ll lmn,lmx,lad,s;//c代表的是count数量,不是次
}t[N<<];int cnt=,rt,n,m,x;
char readchar(){
static char buf[],*l=buf,*r=buf;
if(l==r) r=(l=buf)+fread(buf,,,stdin);
if(l==r) return EOF;return *l++;}
int read(){
int x=,f=;char ch=readchar();
while(ch<''||ch>''){if(ch=='-') f=-f;ch=readchar();}
while(ch<=''&&ch>=''){x=(x<<)+(x<<)+ch-'';ch=readchar();};
return x*f;
} void pushup(int cur){
int ls=t[cur].ls,rs=t[cur].rs;
t[cur].s=t[ls].s+t[rs].s;
if(t[ls].mn1<t[rs].mn1)
t[cur].mn1=t[ls].mn1,
t[cur].mnc=t[ls].mnc,
t[cur].mn2=min(t[ls].mn2,t[rs].mn1);
else if(t[ls].mn1>t[rs].mn1)
t[cur].mn1=t[rs].mn1,
t[cur].mnc=t[rs].mnc,
t[cur].mn2=min(t[rs].mn2,t[ls].mn1);
else t[cur].mn1=t[ls].mn1,
t[cur].mnc=t[ls].mnc+t[rs].mnc,
t[cur].mn2=min(t[ls].mn2,t[rs].mn2);
if(t[ls].mx1>t[rs].mx1)
t[cur].mx1=t[ls].mx1,
t[cur].mxc=t[ls].mxc,
t[cur].mx2=max(t[ls].mx2,t[rs].mx1);
else if(t[ls].mx1<t[rs].mx1)
t[cur].mx1=t[rs].mx1,
t[cur].mxc=t[rs].mxc,
t[cur].mx2=max(t[rs].mx2,t[ls].mx1);
else t[cur].mx1=t[ls].mx1,
t[cur].mxc=t[ls].mxc+t[rs].mxc,
t[cur].mx2=max(t[ls].mx2,t[rs].mx2);
} void adsm(int cur,ll x){
t[cur].mn1+=x;t[cur].mx1+=x;
if(t[cur].mn2!= inf) t[cur].mn2+=x;
if(t[cur].mx2!=-inf) t[cur].mx2+=x;
t[cur].s+=x*(t[cur].r-t[cur].l+);
t[cur].lad+=x;return ;
} void admn(int cur,ll x){
if(t[cur].mn1==t[cur].mx1) t[cur].mx1+=x;
if(t[cur].mn1==t[cur].mx2) t[cur].mx2+=x;
t[cur].lmn+=x;t[cur].mn1+=x;
t[cur].s+=x*t[cur].mnc;return ;
} void admx(int cur,ll x){
if(t[cur].mn1==t[cur].mx1) t[cur].mn1+=x;
if(t[cur].mx1==t[cur].mn2) t[cur].mn2+=x;
t[cur].mx1+=x;t[cur].lmx+=x;
t[cur].s+=x*t[cur].mxc;return ;
} void pushdown(int cur){
int ls=t[cur].ls,rs=t[cur].rs;
if(t[cur].lad) adsm(ls,t[cur].lad),
adsm(rs,t[cur].lad),t[cur].lad=;
if(t[cur].lmn){
if(t[ls].mn1<=t[rs].mn1)
admn(ls,t[cur].lmn);
if(t[ls].mn1>=t[rs].mn1)
admn(rs,t[cur].lmn);t[cur].lmn=;
} if(t[cur].lmx){
if(t[ls].mx1>=t[rs].mx1)
admx(ls,t[cur].lmx);
if(t[ls].mx1<=t[rs].mx1)
admx(rs,t[cur].lmx);t[cur].lmx=;
} return ;
} void build(int l,int r,int cur){
t[cur].l=l,t[cur].r=r;
if(l==r){ t[cur].mxc=;
t[cur].ls=t[cur].rs=-;t[cur].mnc=;
t[cur].lmn=t[cur].lmx=t[cur].lad=;
t[cur].s=t[cur].mx1=t[cur].mn1=read();
t[cur].mn2=inf;t[cur].mx2=-inf;return ;
} int mid=l+r>>;
t[cur].ls=cnt++;t[cur].rs=cnt++;
build(l,mid,t[cur].ls);
build(mid+,r,t[cur].rs);
pushup(cur);return ;
}
#define sum(x,y) x+y;
#define upd(fun,lm,req,tag) \
void fun(int l,int r,int cur){ \
if(lm) return ; \
if(l<=t[cur].l&&t[cur].r<=r&&req) \
{tag;return ;} pushdown(cur); \
int mid=t[cur].l+t[cur].r>>; \
if(l<=mid) fun(l,r,t[cur].ls); \
if(mid<r) fun(l,r,t[cur].rs); \
pushup(cur);return ; \
}
#define qry(fun,typ,ret,op) \
typ fun(int l,int r,int cur){ \
int ls=t[cur].ls,rs=t[cur].rs; \
if(l<=t[cur].l&&t[cur].r<=r) return ret;\
pushdown(cur); \
int mid=t[cur].l+t[cur].r>>; \
if(r<=mid) return fun(l,r,ls); \
if(mid<l) return fun(l,r,rs); \
return op(fun(l,r,ls),fun(l,r,rs)); \
}
upd(uad,,,adsm(cur,x))
upd(umn,t[cur].mn1>=x,t[cur].mn2>x,
admn(cur,x-t[cur].mn1))
upd(umx,t[cur].mx1<=x,t[cur].mx2<x,
admx(cur,x-t[cur].mx1))
qry(qsm,ll,t[cur].s,sum)
qry(qmx,ll,t[cur].mx1,max)
qry(qmn,ll,t[cur].mn1,min)
signed main(){
rt=cnt++;n=read();
build(,n,rt);m=read();
for(int l,r,op;m--;){
op=read();l=read();r=read();
if(op<=) x=read();
if(op==) uad(l,r,rt);
if(op==) umn(l,r,rt);
if(op==) umx(l,r,rt);
if(op==) printf("%lld\n",qsm(l,r,rt));
if(op==) printf("%lld\n",qmx(l,r,rt));
if(op==) printf("%lld\n",qmn(l,r,rt));
} return ;
}

Segment Tree Beats!

BZOJ 4695 最假女选手 线段树的更多相关文章

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

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

  2. bzoj 4695 最假女选手 吉利线段树

    最假女选手 Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 480  Solved: 118[Submit][Status][Discuss] Desc ...

  3. bzoj 4695: 最假女选手 && Gorgeous Sequence HDU - 5306 && (bzoj5312 冒险 || 小B的序列) && bzoj4355: Play with sequence

    算导: 核算法 给每种操作一个摊还代价(是手工定义的),给数据结构中某些东西一个“信用”值(不是手动定义的,是被动产生的),摊还代价等于实际代价+信用变化量. 当实际代价小于摊还代价时,增加等于差额的 ...

  4. bzoj 4695: 最假女选手

    ……一道丧病线段树膜板题…… 被常数卡的死去活来……QAQ 学到了些奇技淫巧:把取min标记 和 区间最小值 合并 可以快很多…… #include <bits/stdc++.h> #de ...

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

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

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

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

  7. 2018.07.27 bzoj4695: 最假女选手(线段树)

    传送门 线段树好题 支持区间加,区间取min" role="presentation" style="position: relative;"> ...

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

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

  9. [BZOJ 2212] [Poi2011] Tree Rotations 【线段树合并】

    题目链接:BZOJ - 2212 题目分析 子树 x 内的逆序对个数为 :x 左子树内的逆序对个数 + x 右子树内的逆序对个数 + 跨越 x 左子树与右子树的逆序对. 左右子树内部的逆序对与是否交换 ...

随机推荐

  1. 4 Java 如何判定是否存活或者死亡

    在堆中存放着几乎所有的对象实例,垃圾收集器在对堆进行回收前,第一件事就是要确定这些对象之中哪些还活着,哪些对象已经死去. 判断对象是否已经死亡有以下几种算法: 引用计数法算法 定义 : 给对象中添加一 ...

  2. SQL Server OPENQUERY使用

    以下以创建好的ORAC链接服务器为例: A. 执行 SELECT 传递查询 SELECT * FROM OPENQUERY(ORAC, 'SELECT ID,NAME FROM SCOTT.RYB') ...

  3. 使用python计算softmax函数

    softmax计算公式:                        Softmax是机器学习中一个非常重要的工具,他可以兼容 logistics 算法.可以独立作为机器学习的模型进行建模训练.还可 ...

  4. Mybatis的全局配置文件标签介绍(mybatis-config.xml)

    全局配置文件中本人只记录了常用的几个  typeHandlers, objectFactory,objectWrapperFactory, reflectorFactory, plugins, dat ...

  5. JavaScript编程艺术-第6章(JavaScript美术馆改进版)代码

    基于[第4章(JavaScript美术馆)代码]进行改进(***HTML与JS分离***) (*亲测可用) HTML: JS: CSS:

  6. [USACO 2012 Jan Silver] Delivery Route【拆点】

    传送门:http://www.usaco.org/index.php?page=viewproblem2&cpid=106 这道题还真是完全没思路,真的不知道怎么做,但是看了题解后恍然大悟. ...

  7. Android上的进程通信(IPC)机制

    Interprocess Communication Android offers a mechanism for interprocess communication (IPC) using rem ...

  8. XmlPullParser简单教程

    官网: http://www.xmlpull.org 本文参考 : http://www.xmlpull.org/v1/download/unpacked/doc/quick_intro.html 1 ...

  9. C#_JDBC连接数据库

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  10. vue-cli 3 配置打包环境

    从新建项目到设置打包环境 1.vue create vue-cli-env 2.新建 vue.config.js 文件,设置baseUrl: './' 3.新建各个环境的文件,例如:.env.deve ...