HDU - 5306 剪枝的线段树
题意:给定\(a[1...n]\),\(m\)次操作,0表示使\([L,R]\)中的值\(a[i]=min(a[i],x)\),其余的1是查最值2是查区间和
本题是jls的2016论文题,1 2套路不说
对于操作0,维护当前最值和严格次大最值,更新过程分三种情况
1.当前的最大值本来就比\(x\)小或相等,直接剪枝(全局剪枝更优,道理不必多说)
2.当前最大值大于\(x\),次大值小于等于\(x\),那么影响到的值只有最大值,打个tag维护
3.其它情况,暴力dfs
具体地,\(max\)值的改变影响了\(sum\)值,那我们需要维护的tag需要值为\(max\)的个数,此时\(sum\)只需做差相减
论文证明这种操作下依然是\(O(logn)\)的
代码改得比较多,略丑
细节要注意的地方也挺多的
#include<bits/stdc++.h>
#define rep(i,j,k) for(register int i=j;i<=k;i++)
#define rrep(i,j,k) for(register int i=j;i>=k;i--)
#define erep(i,u) for(register int i=head[u];~i;i=nxt[i])
#define print(a) printf("%lld",(ll)a)
#define println(a) printf("%lld\n",(ll)(a))
using namespace std;
const int MAXN = 1e6+11;
const int NN = 1e5+11;
const int INF = 0x3f3f3f3f;
const double EPS = 1e-7;
typedef long long ll;
const ll MOD = 1e9+7;
ll read() {
ll x=0,f=1;register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int a[MAXN];
struct ST{
#define lc o<<1
#define rc o<<1|1
int mx[MAXN<<2],smx[MAXN<<2],mxcnt[MAXN<<2];
ll sum[MAXN<<2];
bool lazy[MAXN<<2];
void pu(int o){
mx[o]=max(mx[lc],mx[rc]);
sum[o]=sum[lc]+sum[rc];
smx[o]=max(smx[lc],smx[rc]);
mxcnt[o]=0;
if(mx[lc]!=mx[rc]) smx[o]=max(smx[o],min(mx[lc],mx[rc]));//
if(mx[lc]==mx[o]) mxcnt[o]+=mxcnt[lc];
if(mx[rc]==mx[o]) mxcnt[o]+=mxcnt[rc];
}
void pd(int o){
if(lazy[o]){
if(mx[lc]>mx[o]){
lazy[lc]=1;
sum[lc]-=1ll*(mx[lc]-mx[o])*mxcnt[lc];
mx[lc]=mx[o];
}
if(mx[rc]>mx[o]){
lazy[rc]=1;
sum[rc]-=1ll*(mx[rc]-mx[o])*mxcnt[rc];
mx[rc]=mx[o];
}
lazy[o]=0;
// lazy[lc]=lazy[rc]=1;
}
}
void build(int o,int l,int r){
mx[o]=smx[o]=-INF;mxcnt[o]=lazy[o]=sum[o]=0;
if(l==r){
sum[o]=mx[o]=a[l];
// smx[o]=-INF;
mxcnt[o]=1;
return;
}
int mid=l+r>>1;
build(lc,l,mid);
build(rc,mid+1,r);
pu(o);
}
void update(int o,int l,int r,int L,int R,int v){
if(mx[o]<=v) return; // 全局剪枝
if(L<=l&&r<=R){
// if(mx[o]<=v)return;
if(smx[o]<=v){//只改变最大值
// pd(o);
lazy[o]=1;
sum[o]-=1ll*(mx[o]-v)*mxcnt[o];
mx[o]=v;//mxcnt bu bian
return;
}
}
pd(o);
int mid=l+r>>1;
if(L<=mid) update(lc,l,mid,L,R,v);
if(R>mid) update(rc,mid+1,r,L,R,v);
pu(o);
}
ll queryMax(int o,int l,int r,int L,int R){
if(L<=l&&r<=R) return mx[o];
pd(o);
int mid=l+r>>1;
ll res=-INF;
if(L<=mid) res=max(res,queryMax(lc,l,mid,L,R));
if(R>mid) res=max(res,queryMax(rc,mid+1,r,L,R));
return res;
}
ll querySum(int o,int l,int r,int L,int R){
if(L<=l&&r<=R) return sum[o];
pd(o);
int mid=l+r>>1;
ll res=0;
if(L<=mid) res+=querySum(lc,l,mid,L,R);
if(R>mid) res+=querySum(rc,mid+1,r,L,R);
return res;
}
}st;
int main(){
int T=read();
while(T--){
int n=read();
int m=read();
rep(i,1,n) a[i]=read();
st.build(1,1,n);
rep(i,1,m){
int op=read();
int x=read();
int y=read();
if(op==0){
int t=read();
st.update(1,1,n,x,y,t);
}else if(op==1){
println(st.queryMax(1,1,n,x,y));
}else{
println(st.querySum(1,1,n,x,y));
}
}
}
return 0;
}
HDU - 5306 剪枝的线段树的更多相关文章
- HDU 5306 Gorgeous Sequence[线段树区间最值操作]
Gorgeous Sequence Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Othe ...
- HDU 5306 吉司机线段树
思路: 后面nlogn的部分是伪证... 大家可以构造数据证明是这是nlog^2n的啊~ 吉老司机翻车了 //By SiriusRen #include <cstdio> #include ...
- HDU - 5306 Gorgeous Sequence 线段树 + 均摊分析
Code: #include<algorithm> #include<cstdio> #include<cstring> #define ll long long ...
- hdu 5700区间交(线段树)
区间交 Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submiss ...
- Snacks HDU 5692 dfs序列+线段树
Snacks HDU 5692 dfs序列+线段树 题意 百度科技园内有n个零食机,零食机之间通过n−1条路相互连通.每个零食机都有一个值v,表示为小度熊提供零食的价值. 由于零食被频繁的消耗和补充, ...
- HDU 5091---Beam Cannon(线段树+扫描线)
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5091 Problem Description Recently, the γ galaxies bro ...
- HDU 1542 Atlantis(线段树扫描线+离散化求面积的并)
Atlantis Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- HDU 4031 Attack(线段树/树状数组区间更新单点查询+暴力)
Attack Time Limit: 5000/3000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others) Total Sub ...
- HDU 5820 (可持久化线段树)
Problem Lights (HDU 5820) 题目大意 在一个大小为50000*50000的矩形中,有n个路灯.(n<=500000) 询问是否每一对路灯之间存在一条道路,使得长度为|x1 ...
随机推荐
- mybatis思维导图(一)
写在前面 与hibernate相比,我无疑更喜欢mybatis,就因为我觉得它真的好用,哈哈.它简单上手和掌握:sql语句和代码分开,方便统一管理和优化:当然缺点也有:sql工作量很大,尤其是字段多. ...
- HttpUploader2-queue版本
1.1 2016版本 目标: 1.大幅度优化JS代码,面向开发人员更加友好,逻辑清晰,代码简洁,便于阅读,定制开发,扩展,更加符合企业级应用需求. 2.大幅度使用并发技术来提高上传速度,与HttpUp ...
- WordPaster-Drupal 7.34-CKEditor4x
1.1. 集成到drupal 7x-ck4 插件下载:Drupal 7x, 1.1.1. 安装ckeditor4x 下载插件 说明:下载并解压 CKEditor4x插件:https://yunpan. ...
- 敏捷软件开发:原则、模式与实践——第13章 写给C#程序员的UML概述
第13章 写给C#程序员的UML概述 UML包含3类主要的图示.静态图(static diagram)描述了类.对象.数据结构以及它们之间的关系,藉此表现出了软件元素间那些不变的逻辑结构.动态图(dy ...
- 设计模式1---单例模式(Singleton pattern)
单例模式Singleton 面试的时候,问到许多年轻的Android开发他所会的设计模式是什么,基本上都会提到单例模式,但是对 单例模式也是一知半解,在Android开发中我们经常会运用单例模式,所以 ...
- hdu2993 MAX Average Problem (斜率dp)
参考:http://www.cnblogs.com/kuangbin/archive/2012/08/27/2657878.html //#pragma warning (disable: 4786) ...
- MongoDB整理笔记のjava MongoDB分页优化
最近项目在做网站用户数据新访客统计,数据存储在MongoDB中,统计的数据其实也并不是很大,1000W上下,但是公司只配给我4G内存的电脑,让我程序跑起来气喘吁吁...很是疲惫不堪. 最常见的问题莫过 ...
- mysql数据库使用sql查询数据库大小及表大小
网上查了很多资料,最后发现一个可行的,分享如下: 数据库大小查询: select concat(round(sum(DATA_LENGTH/1024/1024),2),'M') from inform ...
- django LookUp
Custom Lookups 一个简单LookUp例子 Author.objects.filter(name__ne='Jack') # Translate SQL "author" ...
- Foxman, 基于微核架构的 Mock 解决方案
本文来自 网易云社区 . Foxman ⇗ 是一个使用 Node.js 开发的命令行工具,定位是一个可扩展的 Mock Server,帮助前端开发者轻松.独立.高效地进行前端开发和完成后续的联调工作. ...