【hdu5306】 Gorgeous Sequence
http://acm.hdu.edu.cn/showproblem.php?pid=5306 (题目链接)
题意
区间取$min$操作,区间求和操作,区间求最值操作。
Solution
乱搞一通竟然AC了= =,具体参考吉如一论文。蒯一发上来方便自己以后看嘿嘿。
对线段树中的每一个节点除了维护区间最值和区间和以外,还要额外维护区间中的最大值$ma$,严格次大值$se$以及最大值个数$t$。
现在假设我们要让区间$[L,R]$对$x$取$\min$,我们先在线段树中定位这个区间,对定位的每一个节点,我们开始暴力搜索。搜索到的每一个节点分三种情况进行讨论:
- 当$ma \leq x$时,显然这一次修改不会对这个节点产生影响,直接退出。
- 当$se<x<ma$时,显然这一次修改只会影响所有最大值,所以我们把$sum$加上$t*(x-ma)$,把$ma$更新为$x$,接着打上标记以后退出。
- 当$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的更多相关文章
- 【hdu5306】Gorgeous Sequence 线段树区间最值操作
题目描述 给你一个序列,支持三种操作: $0\ x\ y\ t$ :将 $[x,y]$ 内大于 $t$ 的数变为 $t$ :$1\ x\ y$ :求 $[x,y]$ 内所有数的最大值:$2\ x\ y ...
- 【HDU5306】Gorgeous Sequence
这个题目是Segment-Tree-beats的论文的第一题. 首先我们考虑下这个问题的不同之处在于,有一个区间对x取max的操作. 那么如何维护这个操作呢? 就是对于线段树的区间,维护一个最大值标记 ...
- 【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 题解:首先很明显就是线段树裸题,那么考虑如何维护 ...
- 【arc071f】Infinite Sequence(动态规划)
[arc071f]Infinite Sequence(动态规划) 题面 atcoder 洛谷 题解 不难发现如果两个不为\(1\)的数连在一起,那么后面所有数都必须相等. 设\(f[i]\)表示\([ ...
- 【arc074e】RGB Sequence(动态规划)
[arc074e]RGB Sequence(动态规划) 题面 atcoder 洛谷 翻译见洛谷 题解 直接考虑暴力\(dp\),设\(f[i][j][k][l]\)表示当前考虑到第\(i\)位,最后一 ...
- 【BZOJ1367】[Baltic2004]sequence 左偏树
[BZOJ1367][Baltic2004]sequence Description Input Output 一个整数R Sample Input 7 9 4 8 20 14 15 18 Sampl ...
- 【BZOJ3043】IncDec Sequence 乱搞
[BZOJ3043]IncDec Sequence Description 给定一个长度为n的数列{a1,a2...an},每次可以选择一个区间[l,r],使这个区间内的数都加一或者都减一.问至少需要 ...
- 【POJ2778】DNA Sequence(AC自动机,DP)
题意: 生物课上我们学到,DNA序列中只有A, C, T和G四种片段. 经科学发现,DNA序列中,包含某些片段会产生不好的基因,如片段"ATC"是不好片段,则"AGATC ...
- 【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 ...
随机推荐
- ActiveMQ在C#中的应用
本文是在.NET Framework框架下的应用,截止到目前ActiveMQ还不支持.NET Core,而RabbitMQ已经支持.NET Core,希望ActiveMQ能尽快支持. ActiveMQ ...
- python中和生成器协程相关的yield之最详最强解释,一看就懂(一)
yield是python中一个非常重要的关键词,所有迭代器都是yield实现的,学习python,如果不把这个yield的意思和用法彻底搞清楚,学习python的生成器,协程和异步io的时候,就会彻底 ...
- JVM规范系列第5章:加载、链接与初始化
加载是根据特定名称查找类或接口类型的二进制表示(Binary Representation),并由此二进制表示创建类或接口的过程. 加载,就是指去寻找类或接口的过程. 链接是为了让类或接口可以被 Ja ...
- JQuery_自带的动画效果
1.方法: show:显示选中元素. hide:隐藏选中元素. toggle:显示或隐藏选中元素. fadeIn:将选中元素的不透明度逐步提升到100%. fadeOut:将选中元素的不透明度逐步降为 ...
- dpkg:错误:正在解析文件 '/var/lib/dpkg/updates/0014' 第 0 行附近:在字段名 #padding 中有换行符问题的解决方法
解决方案如下: sudo rm /var/lib/dpkg/updates/* sudo apt-get update python@ubuntu:~/Desktop/_Welcome_.jpg.ex ...
- ANSYS - 修改节点荷载的规则
问题: 分别在不同的荷载步对同一节点施加集中荷载,则节点最终所受荷载为各步荷载值叠加还是最后一步荷载值? 如,在第一个荷载步对节点n施加集中荷载F1,在第二个荷载步对该节点施加集中荷载F2,则第二个荷 ...
- beta阶段性能指标测试
性能指标概况 安装耗时 启动耗时 CPU占用 内存占用 电池温度 网络流量 平均值 5.48s 1.04s 1.61% 18.68MB 32.44℃ 93.78B 峰值 131.74s 5.13s 5 ...
- CI框架--数据库Query_Builder中的方法
下面是DB_Query_Builder.php中,各个方法的声明: 选择字段(select) public function select($select = '*', $escape = NULL) ...
- SMBv1 is not installed by default in Windows 10 Fall Creators Update 2017 and Windows Server, Semi-annual Channel
windows 10 rs3 release enable SMBv1 windows 10 rs3 release file sharing https://support.microsoft.co ...
- How to leave the open file in eclipse tab after search?
https://superuser.com/questions/130353/how-to-leave-the-open-file-in-eclipse-tab-after-search From m ...