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. RabbitMQ TroubleShooting

    RabbitMQ是一款优秀的消息队列中间件,提供了稳定.监控完善的产品,但是软件就会有bug.为了前进路径可以畅通,我们必须了解出现的一些故障的快速处理方式,毕竟在生产环境,时间就是生命,尽快的处理是 ...

  2. vim命令记录

    最近开始用vim作为日常编辑器,由于vim的命令过多,现在记录一下

  3. @Pointcut的用法

    在Spring 2.0中,Pointcut的定义包括两个部分:Pointcut表示式(expression)和Pointcut签名(signature).让我们先看看execution表示式的格式: ...

  4. Visual studio2015 编译时提示“GenerateResource”任务意外失败。

    今天弄了一个winfrom程序,狗血,一直报错,在另一台电脑上就不报错. 错误如下图 其实这样也能运行,但就是代码改之后,没有办法调试.搜了很久,发现了一种解决办法,完美解决. 最终成功了.

  5. SCRUM 12.23

    距离第二轮迭结束只有几天了. 我们全体组员现在的工作方向都在应用测试上. 明天的任务分配如下 成员 已完成任务 新任务 彭林江 落实API 自动爬虫测试 王卓 提升爬虫程序性能 正确性测试 郝倩 提升 ...

  6. Linux内核分析——第五章 系统调用

    第五章 系统调用 5.1 与内核通信 1.系统调用在用户空间进程和硬件设备之间添加了一个中间层,该层主要作用有三个: (1)为用户空间提供了一种硬件的抽象接口 (2)系统调用保证了系统的稳定和安全 ( ...

  7. Orcle安装环境及步骤

    Windows7环境下如何成功安装Oracle数据库      随着微软新一代操作系统 Windows7 的正式发行,使用 Windows7  的朋友也越来越多,很多人在 Windows7 环境下安装 ...

  8. 第三个spring冲刺第3天

    基本功能跟界面都完成了,今天小组开了个会,基于跟别的小组对比的效果,感觉自己组的效果没别人的好,很多方面还欠缺,所以我们会继续跟进完善.

  9. Hacked VisualSVN Server by PHP to allow user change password

    index.php <?php$username = $_SERVER["PHP_AUTH_USER"]; //经过 AuthType Basic 认证的用户名$authed ...

  10. Bootstrap @Media分类

      手机的屏幕比较小,宽度通常在600像素以下:PC的屏幕宽度,一般都在1000像素以上(目前主流宽度是1366×768)设置相应的min-width和max-width值 所以响应式设计一般对600 ...