【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 ...
随机推荐
- JDK1.7 HashMap 导致循环链表
转载自:疫苗:JAVA HASHMAP的死循环 在淘宝内网里看到同事发了贴说了一个CPU被100%的线上故障,并且这个事发生了很多次,原因是在Java语言在并发情况下使用HashMap造成Race C ...
- .net core实践系列之短信服务-为什么选择.net core(开篇)
前言 从今天我将会写.net core实战系列,以我最近完成的短信服务作为例子.该系列将会尽量以最短的时间全部发布出来.源码也将优先开源出来给大家. 源码地址:https://github.com/S ...
- C#大型电商项目优化(二)——嫌弃EF与抛弃EF
上一篇博文中讲述了使用EF开发电商项目的代码基础篇,提到EF后,一语激起千层浪.不少园友纷纷表示:EF不适合增长速度飞快的互联网项目,EF只适合企业级应用等等. 也有部分高手提到了分布式,确实,性能优 ...
- Slurm任务调度系统部署和测试(源码)(1)
1. 概述1.1 节点信息2. 节点准备3. 部署NTP服务器4. 部署LDAP服务器5. 部署Munge认证服务6. 部署Mysql数据库服务7. 部署slurm7.1 创建slurm用户7.2 挂 ...
- python-深浅copy-18
# 赋值运算l1 = [1,2,3]l2 = l1l1.append('a')print(l1,l2) # [1, 2, 3, 'a'] [1, 2, 3, 'a'] #copyl1 = [1,2,3 ...
- 个人实验 github地址:https://github.com/quchengyu/cher
一.实践目的 1.掌握类的定义,对象的创建. 2.掌握实现封装.继承.多态的方法,掌握各种修饰符的使用. 3.掌握将对象数组作为方法的参数和返回值. 4.掌握抽象类与接口的概念及实现,理解动态绑定机制 ...
- Sprint 冲刺第三阶段第6-10天
这几天一直都在整理我们之前的内容,检查会不会有细节问题.例如界面跳转.颜色等. 因为一直没办法找到guitub存放位置.于是在这里存放一些主代码. MainActivity.java package ...
- Markdown页内跳转实现方法
目录 Markdown页内跳转实现方法 HTML锚点跳转 生成目录 Markdown页内跳转实现方法 [时间:2017-02] [状态:Open] [关键词:markdown,标记语言,页内跳转,ht ...
- HTML 页面的 批量删除的按钮
function delAll(){ var sid=""; $("[name='ids']:checked").each(function(){ sid+=$ ...
- Eclipse的Jar包解压出System.js里String与Boolean定义分号可有可无吗?
Eclipse的Jar包解压出System.js里String与Boolean定义分号可有可无吗? org.eclipse.wst.jsdt.core_1.3.300.v201410221502\li ...