这个题目是Segment-Tree-beats的论文的第一题。

首先我们考虑下这个问题的不同之处在于,有一个区间对x取max的操作。

那么如何维护这个操作呢?

就是对于线段树的区间,维护一个最大值标记,最大值出现次数,以及严格次大值。

接下来考虑处理操作。

首先如果x>maxv[o]证明已经是无所谓的,所以应该直接放弃。

如果v处于semx[o]<x<maxv[o],证明只有最大值需要被修改。

其他的情况就继续向下递进就可以了。

那么我们证明一下为什么这么做复杂度是对的。

首先,如同论文中所说的,对于每个maxv可以看作是一个标记,把相同的maxv合并到第一个点,

可以发现semx的含义就是子树中最大的maxv。(因为最大值已经被缩到了这个点上)

每次暴力进入这些节点的时候,实际上就是将标记进行合并。

(也就是文章中所说的标记回收的理论)

这个题的难点就是为什么我这么暴力的回收依然可以是一个log的。

在每一次操作后会产生一类新的标记。

那么每次标记回收实际上就是有一类标记的权值-=1

#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const int N=1e6+;
int a[N],n,m;
struct Segment_Tree{
#define lson (o<<1)
#define rson (o<<1|1)
int maxv[N<<],cntv[N<<],semx[N<<];
ll sumv[N<<];
inline void pushup(int o){
sumv[o]=sumv[lson]+sumv[rson];
maxv[o]=max(maxv[lson],maxv[rson]);
semx[o]=max(semx[lson],semx[rson]);cntv[o]=;
if(maxv[lson]!=maxv[rson])semx[o]=max(semx[o],min(maxv[lson],maxv[rson]));
if(maxv[o]==maxv[lson])cntv[o]+=cntv[lson];
if(maxv[o]==maxv[rson])cntv[o]+=cntv[rson];
}
inline void puttag(int o,int v){
if(v>=maxv[o])return;
sumv[o]+=1LL*(v-maxv[o])*cntv[o];maxv[o]=v;
}
inline void pushdown(int o){puttag(lson,maxv[o]);puttag(rson,maxv[o]);}
inline void build(int o,int l,int r){
if(l==r){
sumv[o]=maxv[o]=a[l];cntv[o]=;semx[o]=-;
return;
}
int mid=(l+r)>>;
build(lson,l,mid);build(rson,mid+,r);
pushup(o);
}
inline void optmax(int o,int l,int r,int ql,int qr,int v){
if(v>=maxv[o])return;
if(ql<=l&&r<=qr&&v>semx[o]){puttag(o,v);return;}
int mid=(l+r)>>;pushdown(o);
if(ql<=mid)optmax(lson,l,mid,ql,qr,v);
if(qr>mid)optmax(rson,mid+,r,ql,qr,v);
pushup(o);
}
inline ll querysum(int o,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr)return sumv[o];
int mid=(l+r)>>;pushdown(o);ll ans=;
if(ql<=mid)ans+=querysum(lson,l,mid,ql,qr);
if(qr>mid)ans+=querysum(rson,mid+,r,ql,qr);
return ans;
}
inline int querymax(int o,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr)return maxv[o];
pushdown(o);int mid=(l+r)>>,ans=-;
if(ql<=mid)ans=max(ans,querymax(lson,l,mid,ql,qr));
if(qr>mid)ans=max(ans,querymax(rson,mid+,r,ql,qr));
return ans;
}
}sgt;
inline int read(){
int f=,x=;char ch;
do{ch=getchar();if(ch=='-')f=-;}while(ch<''||ch>'');
do{x=x*+ch-'';ch=getchar();}while(ch>=''&&ch<='');
return f*x;
}
int main(){
int T=read();
while(T--){
n=read();m=read();
for(int i=;i<=n;i++)a[i]=read();
sgt.build(,,n);
while(m--){
int opt=read(),l=read(),r=read();
if(opt==){
int v=read();
sgt.optmax(,,n,l,r,v);
}
if(opt==)printf("%d\n",sgt.querymax(,,n,l,r));
if(opt==)printf("%lld\n",sgt.querysum(,,n,l,r));
}
}
}

【HDU5306】Gorgeous Sequence的更多相关文章

  1. 【hdu5306】 Gorgeous Sequence

    http://acm.hdu.edu.cn/showproblem.php?pid=5306 (题目链接) 题意 区间取$min$操作,区间求和操作,区间求最值操作. Solution 乱搞一通竟然A ...

  2. 【hdu5306】Gorgeous Sequence 线段树区间最值操作

    题目描述 给你一个序列,支持三种操作: $0\ x\ y\ t$ :将 $[x,y]$ 内大于 $t$ 的数变为 $t$ :$1\ x\ y$ :求 $[x,y]$ 内所有数的最大值:$2\ x\ y ...

  3. 【HDU5306】【DTOJ2481】Gorgeous Sequence【线段树】

    题目大意:给你一个序列a,你有三个操作,0: x y t将a[x,y]和t取min:1:x y求a[x,y]的最大值:2:x y求a[x,y]的sum 题解:首先很明显就是线段树裸题,那么考虑如何维护 ...

  4. 【arc071f】Infinite Sequence(动态规划)

    [arc071f]Infinite Sequence(动态规划) 题面 atcoder 洛谷 题解 不难发现如果两个不为\(1\)的数连在一起,那么后面所有数都必须相等. 设\(f[i]\)表示\([ ...

  5. 【arc074e】RGB Sequence(动态规划)

    [arc074e]RGB Sequence(动态规划) 题面 atcoder 洛谷 翻译见洛谷 题解 直接考虑暴力\(dp\),设\(f[i][j][k][l]\)表示当前考虑到第\(i\)位,最后一 ...

  6. 【BZOJ1367】[Baltic2004]sequence 左偏树

    [BZOJ1367][Baltic2004]sequence Description Input Output 一个整数R Sample Input 7 9 4 8 20 14 15 18 Sampl ...

  7. 【BZOJ3043】IncDec Sequence 乱搞

    [BZOJ3043]IncDec Sequence Description 给定一个长度为n的数列{a1,a2...an},每次可以选择一个区间[l,r],使这个区间内的数都加一或者都减一.问至少需要 ...

  8. 【POJ2778】DNA Sequence(AC自动机,DP)

    题意: 生物课上我们学到,DNA序列中只有A, C, T和G四种片段. 经科学发现,DNA序列中,包含某些片段会产生不好的基因,如片段"ATC"是不好片段,则"AGATC ...

  9. 【leetcode】 Permutation Sequence (middle)

    The set [1,2,3,…,n] contains a total of n! unique permutations. By listing and labeling all of the p ...

随机推荐

  1. 【bzoj1634】[Usaco2007 Jan]Protecting the Flowers 护花 贪心

    题目描述 Farmer John went to cut some wood and left N (2 <= N <= 100,000) cows eating the grass, a ...

  2. 【bzoj1030】[JSOI2007]文本生成器 AC自动机+dp

    题目描述 JSOI交给队员ZYX一个任务,编制一个称之为“文本生成器”的电脑软件:该软件的使用者是一些低幼人群,他们现在使用的是GW文本生成器v6版.该软件可以随机生成一些文章―――总是生成一篇长度固 ...

  3. COGS 705——回家

    描述 USACO 2.4.4 现在是晚餐时间,而母牛们在外面分散的牧场中. 农民约翰按响了电铃,所以她们开始向谷仓走去. 你的工作是要指出哪只母牛会最先到达谷仓(在给出的测试数据中,总会有且只有一只最 ...

  4. (二)Redis字符串String操作

    String全部命令如下: set key value # 设置一个key的value值 get key # 获取key的value值 mset key1 value1 key2 value2 ... ...

  5. Necklace - CF613C

    Ivan wants to make a necklace as a present to his beloved girl. A necklace is a cyclic sequence of b ...

  6. [洛谷P4070][SDOI2016]生成魔咒

    题目大意:有一个字符串,每次在末尾加入一个字符,问当前共有多少个本质不同的字串 题解:$SAM$,就是问插入这个字符后,多了多少个字串,就是当前这个点的$Right$数组大小. 卡点:无 C++ Co ...

  7. Codeforces Round #469 (Div. 2) F. Curfew

    贪心 题目大意,有2个宿管分别从1和n开始检查房间,记录人数不为n的房间个数,然后锁住房间. 没有被锁的房间中的学生可以选择藏在床底,留在原地,或者转移(最远转移d个房间)   然后抄了网上大神的代码 ...

  8. 20165218 2017-2018-1《Java程序设计》第二周学习总结

    20165218 2017-2018-1 <Java程序设计>第2周学习总结 教材学习内容总结 Ch2 基本数据类型与数组 Unicode字符集之中所有都叫做"字母", ...

  9. Promise用法总结

    1. Promise的状态   Promise对象有三个状态: 1. 进行中(pending) 2. 成功(resolved) 3. 失败(rejected)   2. 生成一个Promise对象   ...

  10. Java中equals和==的区别?为什么重写equals方法后,一定要重写hashCode方法?

    首先明确一点,equals是方法,==是操作符. 1. 如果比较的是基本数据类型: 只讨论==,因为equals是不存在的,因为java中基本数据类型不能调用method的. 2. 如果比较的是引用类 ...