HDU 5306 Gorgeous Sequence
如果维护max,sum,那么可以得到一个暴力方法,如果t>=max,那可以return,否则往下更新,显然超时。
在上面基础上,再维护一下次大值,与最大值的个数。这样一来,次大值<t<最大值 这样的情况也可以更新完了之后直接return,pushDown的话也很好操作。
实践证明,这样的复杂度降到了nlog(n),具体证明可以看吉如一论文。
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0),eps=1e-;
void File()
{
freopen("D:\\in.txt","r",stdin);
freopen("D:\\out.txt","w",stdout);
}
template <class T>
inline void read(T &x)
{
char c = getchar(); x = ;while(!isdigit(c)) c = getchar();
while(isdigit(c)) { x = x * + c - ''; c = getchar(); }
} const int maxn=;
struct Seg
{
LL sum; int a,b,num;
bool flag;
}s[*maxn];
int T,n,m; int M(int a,int b)
{
if(a>b) return a;
return b;
} int CI(int x,int a,int b,int c,int d)
{
if(a==b&&a==c&&a==d) return x;
int res=;
if(a!=x) res=M(res,a);
if(b!=x) res=M(res,b);
if(c!=x) res=M(res,c);
if(d!=x) res=M(res,d);
return res;
} void pushUp(int rt)
{
s[rt].sum=s[*rt].sum+s[*rt+].sum;
s[rt].a=M(s[*rt].a,s[*rt+].a);
s[rt].b=CI(s[rt].a,s[*rt].a,s[*rt].b,s[*rt+].a,s[*rt+].b);
s[rt].num=;
if(s[*rt].a==s[rt].a) s[rt].num=s[rt].num+s[*rt].num;
if(s[*rt+].a==s[rt].a) s[rt].num=s[rt].num+s[*rt+].num;
} void pushDown(int rt)
{
if(s[rt].flag==) return;
int MAX=M(s[*rt].a,s[*rt+].a);
int t=s[rt].a;
if(s[*rt].a==MAX)
{
s[*rt].flag=;
s[*rt].sum=s[*rt].sum-(LL)(s[*rt].a-t)*s[*rt].num;
if(s[*rt].a==s[*rt].b) s[*rt].a=s[*rt].b=t;
else s[*rt].a=t;
} if(s[*rt+].a==MAX)
{
s[*rt+].flag=;
s[*rt+].sum=s[*rt+].sum-(LL)(s[*rt+].a-t)*s[*rt+].num;
if(s[*rt+].a==s[*rt+].b) s[*rt+].a=s[*rt+].b=t;
else s[*rt+].a=t;
}
s[rt].flag=;
} void build(int l,int r,int rt)
{
s[rt].num=s[rt].a=s[rt].b=s[rt].sum=;
s[rt].flag=;
if(l==r)
{
scanf("%d",&s[rt].a);
s[rt].b=s[rt].a;
s[rt].sum=(LL)s[rt].b;
s[rt].num=;
return;
}
int m=(l+r)/;
build(l,m,*rt);
build(m+,r,*rt+);
pushUp(rt);
} int f(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R) return s[rt].a;
int m=(l+r)/;
int x1=,x2=;
pushDown(rt);
if(L<=m) x1=f(L,R,l,m,*rt);
if(R>m) x2=f(L,R,m+,r,*rt+);
pushUp(rt);
return max(x1,x2);
} LL sum(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R) return s[rt].sum;
int m=(l+r)/;
LL x1=,x2=; pushDown(rt);
if(L<=m) x1=sum(L,R,l,m,*rt);
if(R>m) x2=sum(L,R,m+,r,*rt+);
pushUp(rt); return x1+x2; } void force(int t,int l,int r,int rt)
{
if(s[rt].a<=t) return; if(l==r)
{
s[rt].a=s[rt].b=s[rt].sum=t;
return ;
} if(s[rt].b<t)
{
s[rt].flag=;
s[rt].sum=s[rt].sum-(LL)(s[rt].a-t)*s[rt].num;
s[rt].a=t;
return;
} if(s[rt].b==s[rt].a)
{
s[rt].flag=;
s[rt].sum=s[rt].sum-(LL)(s[rt].a-t)*s[rt].num;
s[rt].b=s[rt].a=t;
return;
} pushDown(rt);
int m=(l+r)/,tag=;
if(s[*rt].a>t) force(t,l,m,*rt),tag=;
if(s[*rt+].a>t) force(t,m+,r,*rt+),tag=;
if(tag==) pushUp(rt);
} void update(int L,int R,int t,int l,int r,int rt)
{
if(s[rt].a<=t) return; if(L<=l&&r<=R)
{
force(t,l,r,rt);
return ;
}
pushDown(rt);
int m=(l+r)/,tag=;
if(L<=m&&s[*rt].a>t) update(L,R,t,l,m,*rt),tag=;
if(R>m&&s[*rt+].a>t) update(L,R,t,m+,r,*rt+),tag=;
if(tag==) pushUp(rt);
} int main()
{
scanf("%d",&T); while(T--)
{
scanf("%d%d",&n,&m);
build(,n,);
for(int i=;i<=m;i++)
{
int op,x,y;
scanf("%d%d%d",&op,&x,&y);
if(op==)
{
int t; read(t);
update(x,y,t,,n,);
}
else if(op==) printf("%d\n",f(x,y,,n,));
else printf("%lld\n",sum(x,y,,n,));
}
}
return ;
}
HDU 5306 Gorgeous Sequence的更多相关文章
- HDU 5306 Gorgeous Sequence[线段树区间最值操作]
Gorgeous Sequence Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Othe ...
- 2015 Multi-University Training Contest 2 hdu 5306 Gorgeous Sequence
Gorgeous Sequence Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Othe ...
- [HDU] 5306 Gorgeous Sequence [区间取min&求和&求max]
题解: 线段树维护区间取min求和求max 维护最小值以及个数,次小值 标记清除时,分情况讨论 当lazy>max1 退出 当max1>lazy>max2(注意不要有等号) 更新 否 ...
- HDU - 5306 Gorgeous Sequence (吉司机线段树)
题目链接 吉司机线段树裸题... #include<bits/stdc++.h> using namespace std; typedef long long ll; ,inf=0x3f3 ...
- HDU - 5306 Gorgeous Sequence 线段树 + 均摊分析
Code: #include<algorithm> #include<cstdio> #include<cstring> #define ll long long ...
- HDOJ 5306 Gorgeous Sequence 线段树
http://www.shuizilong.com/house/archives/hdu-5306-gorgeous-sequence/ Gorgeous Sequence Time Limit: 6 ...
- HDU 5860 Death Sequence(死亡序列)
p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: Calibri; font-s ...
- HDU 1711 Number Sequence(数列)
HDU 1711 Number Sequence(数列) Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Ja ...
- HDU 1005 Number Sequence(数列)
HDU 1005 Number Sequence(数列) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Jav ...
随机推荐
- Linux学习笔记(一):常用命令(2)
3.帮助命令 A,帮助命令:man B,其他帮助命令 3.1,格式:man [命令名] 查看命令拥有哪个级别的帮助: ...
- 关于CachedRowSetImpl类
全称: com.sun.rowset.CachedRowSetImpl 父类: javax.sql.rowset.BaseRowSet 实现的接口: javax.sql.RowSet javax.sq ...
- js中的document.body.scrollTop与document.documentElement.scrollTop
获取当前页面滚动条纵坐标的位置:document.body.scrollTop与document.documentElement.scrollTop获取当前页面滚动条横坐标的位置:document.b ...
- IIS配置 Web部署 svg/woff/woff2字体 404错误
一,woff/woff2字体 404错误,这个可以在浏览器按F12的Console页面可以发现问题,如下图: 解决方法: 一,打开服务器IIS管理器,找到MIME类型 二,添加MIME类型 添加三条: ...
- Linux 中 sudo、su命令
sudo : 暂时切换到超级用户模式以执行超级用户权限,提示输入密码时该密码为当前用户的密码,而不是超级账户的密码.不过有时间限制,Ubuntu默认为一次时长15分钟.su : 切换到某某用户模式,提 ...
- database disk image is malformed
在Linux上使用yum安装软件的时候报如下错误: database disk image is malformed 根本原因是:yum的缓存出错, 需要清理缓存 使用如下命令来解决这个问题: yum ...
- js时间戳转换时间格式
function getLocalTime(time){ if(time > 0){ var dateStr = new Date(time * 1000); var str = "& ...
- 面试题-Java基础-面向对象
1.面向对象软件开发的优点有哪些? 代码开发模块化,更易维护和修改.代码复用.增强代码的可靠性和灵活性.增加代码的可理解性.面向对象编程有很多重要的特性,比如:封装,继承,多态和抽象.下面的章节我们会 ...
- CodeForces 712D Memory and Scores
$dp$,前缀和. 记$dp[i][j]$表示$i$轮结束之后,两人差值为$j$的方案数. 转移很容易想到,但是转移的复杂度是$O(2*k)$的,需要优化,观察一下可以发现可以用过前缀和来优化. 我把 ...
- C#基础、基础知识点(新人自我总结,开启java学习之路)
从2016年12月29开班,开课到现在C#基础已经算是简答的学习了一点,一个为期两周的课程,或多或少对现在学的Java有着一定的帮助吧,我们先从软件入门来接触c#这门语言: 一.软件开发中的常用术语: ...