http://acm.hdu.edu.cn/showproblem.php?pid=5306 (题目链接)

题意

  区间取$min$操作,区间求和操作,区间求最值操作。

Solution

  乱搞一通竟然AC了= =,具体参考吉如一论文。蒯一发上来方便自己以后看嘿嘿。

  对线段树中的每一个节点除了维护区间最值和区间和以外,还要额外维护区间中的最大值$ma$,严格次大值$se$以及最大值个数$t$。

  现在假设我们要让区间$[L,R]$对$x$取$\min$,我们先在线段树中定位这个区间,对定位的每一个节点,我们开始暴力搜索。搜索到的每一个节点分三种情况进行讨论:

  1. 当$ma \leq x$时,显然这一次修改不会对这个节点产生影响,直接退出。
  2. 当$se<x<ma$时,显然这一次修改只会影响所有最大值,所以我们把$sum$加上$t*(x-ma)$,把$ma$更新为$x$,接着打上标记以后退出。
  3. 当$x \leq se$时,我们无法直接更新这个节点的信息,因此在这时,我们对当前节点的左右儿子递归搜索。

  好暴力的做法,然而复杂度证明是玄学的势能分析,嗯我是实践派。

细节

  LL,也许你需要一发读入优化= =。

代码

// hdu5306
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define inf (1ll<<30)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout)
using namespace std;
inline int gi() {
int x=0;char ch=getchar();
while (ch<'0' || ch>'9') ch=getchar();
while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();}
return x;
} const int maxn=1000010;
int n,m,a[maxn];
struct node {int l,r,t,ma,se,tag;LL s;}tr[maxn<<2]; void pushup(int k) {
int l=k<<1,r=k<<1|1;
if (tr[l].ma==tr[r].ma) {
tr[k].ma=tr[l].ma,tr[k].t=tr[l].t+tr[r].t;
tr[k].se=max(tr[l].se,tr[r].se);
}
else if (tr[l].ma<tr[r].ma) {
tr[k].ma=tr[r].ma,tr[k].t=tr[r].t;
tr[k].se=max(tr[l].ma,tr[r].se);
}
else {
tr[k].ma=tr[l].ma,tr[k].t=tr[l].t;
tr[k].se=max(tr[l].se,tr[r].ma);
}
tr[k].s=tr[l].s+tr[r].s;
}
void pushdown(int k) {
int l=k<<1,r=k<<1|1,val=tr[k].ma;
if (tr[l].se<val && tr[l].ma>val) {
tr[l].s-=1LL*tr[l].t*(tr[l].ma-val);
tr[l].ma=val;tr[l].tag=1;
}
if (tr[r].se<val && tr[r].ma>val) {
tr[r].s-=1LL*tr[r].t*(tr[r].ma-val);
tr[r].ma=val;tr[r].tag=1;
}
tr[k].tag=0;
} void build(int k,int s,int t) {
tr[k].l=s,tr[k].r=t;tr[k].se=-1;tr[k].tag=0;
if (s==t) {tr[k].s=tr[k].ma=a[s];tr[k].t=1;return;}
int mid=(s+t)>>1;
build(k<<1,s,mid);
build(k<<1|1,mid+1,t);
pushup(k);
}
void modify(int k,int s,int t,int val) {
int l=tr[k].l,r=tr[k].r,mid=(l+r)>>1;
if (l==s && r==t) {
if (val>=tr[k].ma) return;
if (tr[k].se<val) {
tr[k].s-=1LL*tr[k].t*(tr[k].ma-val);
tr[k].ma=val;tr[k].tag=1;
return;
}
}
if (tr[k].tag) pushdown(k);
if (t<=mid) modify(k<<1,s,t,val);
else if (s>mid) modify(k<<1|1,s,t,val);
else modify(k<<1,s,mid,val),modify(k<<1|1,mid+1,t,val);
pushup(k);
}
int querymx(int k,int s,int t) {
int l=tr[k].l,r=tr[k].r,mid=(l+r)>>1;
if (l==s && r==t) return tr[k].ma;
if (tr[k].tag) pushdown(k);
if (t<=mid) return querymx(k<<1,s,t);
else if (s>mid) return querymx(k<<1|1,s,t);
else return max(querymx(k<<1,s,mid),querymx(k<<1|1,mid+1,t));
}
LL querysum(int k,int s,int t) {
int l=tr[k].l,r=tr[k].r,mid=(l+r)>>1;
if (l==s && r==t) return tr[k].s;
if (tr[k].tag) pushdown(k);
if (t<=mid) return querysum(k<<1,s,t);
else if (s>mid) return querysum(k<<1|1,s,t);
else return querysum(k<<1,s,mid)+querysum(k<<1|1,mid+1,t);
} int main() {
int T=gi();
while (T--) {
n=gi(),m=gi();
for (int i=1;i<=n;i++) a[i]=gi();
build(1,1,n);
for (int op,x,y,t,i=1;i<=m;i++) {
op=gi(),x=gi(),y=gi();
if (op==0) t=gi(),modify(1,x,y,t);
if (op==1) printf("%d\n",querymx(1,x,y));
if (op==2) printf("%lld\n",querysum(1,x,y));
}
}
return 0;
}

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

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

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

  2. 【HDU5306】Gorgeous Sequence

    这个题目是Segment-Tree-beats的论文的第一题. 首先我们考虑下这个问题的不同之处在于,有一个区间对x取max的操作. 那么如何维护这个操作呢? 就是对于线段树的区间,维护一个最大值标记 ...

  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. Scala学习(六)---Scala对象

    Scala中的对象 摘要: 在本篇中,你将会学到何时使用Scala的object语法结构.在你需要某个类的单个实例时,或者想为其他值或函数找一个可以挂靠的地方时,你就会用到它.本篇的要点包括: 1. ...

  2. Shell编程基础篇-上

    1.1 前言 1.1.1 为什么学Shell Shell脚本语言是实现Linux/UNIX系统管理及自动化运维所必备的重要工具, Linux/UNIX系统的底层及基础应用软件的核心大都涉及Shell脚 ...

  3. RabbitMQ 优先级队列-为队列赋权

    RabbitMQ 消息收发是按顺序收发,一般情况下是先收到的消息先处理,即可以实现先进先出的消息处理.但如果消息者宕机或其他原因,导致消息接收以后,未确认,那么消息会重新Requeue到队列中,就打破 ...

  4. 【下一代核心技术DevOps】:(二)Rancher的应用及优点简介

    1.环境选择 安装Rancher环境,一定要在干净的linux主机上进行,避免出现因配置导致的莫名其妙的问题.服务器操作系统建议CentOS7.4(内核3.10以上)低于这个版本的系统 如7.3 7. ...

  5. Centos下安装破解confluence6.3的操作记录

    confluence是一个专业的企业知识管理与协同软件,可以用于构建企业wiki.通过它可以实现团队成员之间的协作和知识共享.现在大多数公司都会部署一套confluence,用作内部wiki.现在co ...

  6. Shell学习笔记二

    一.调试脚本 调试功能是每一种编程语言都应该实现的重要特性之一,当出现一些始料未及的情况时,用它来生成脚本运行信息.调试信息可以帮你弄清楚是什么原因使得程序发生崩溃或行为异常.每位系统程序员都应该了解 ...

  7. Python-文件操作—_19

    1,文件操作 模特主妇护士老师.txt 1,文件路径:d:\模特主妇护士老师.txt 2,编码方式:utf-8 gbk .... 3,操作方式:只读,只写,追加,读写,写读..... 以什么编码方式储 ...

  8. omnigraffle 的一些总结

    http://jingyan.baidu.com/article/fcb5aff7a16337edab4a714d.html Omnigraffle绘制连接线时从任意点开始 点击直线工具后,在右侧设置 ...

  9. Week 1 工程表格

    PSP2.1 Personal Software Process Stages Time Planning 计划 · Estimate · 估计这个任务需要多少时间 6h30min Developme ...

  10. rabbitMq与spring boot搭配实现监听

    在我前面有一篇博客说到了rabbitMq实现与zk类似的watch功能,但是那一篇博客没有代码实例,后面自己补了一个demo,便于理解.demo中主要利用spring boot的配置方式, 一.消费者 ...