如果维护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的更多相关文章

  1. HDU 5306 Gorgeous Sequence[线段树区间最值操作]

    Gorgeous Sequence Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Othe ...

  2. 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 ...

  3. [HDU] 5306 Gorgeous Sequence [区间取min&求和&求max]

    题解: 线段树维护区间取min求和求max 维护最小值以及个数,次小值 标记清除时,分情况讨论 当lazy>max1 退出 当max1>lazy>max2(注意不要有等号) 更新 否 ...

  4. HDU - 5306 Gorgeous Sequence (吉司机线段树)

    题目链接 吉司机线段树裸题... #include<bits/stdc++.h> using namespace std; typedef long long ll; ,inf=0x3f3 ...

  5. HDU - 5306 Gorgeous Sequence 线段树 + 均摊分析

    Code: #include<algorithm> #include<cstdio> #include<cstring> #define ll long long ...

  6. HDOJ 5306 Gorgeous Sequence 线段树

    http://www.shuizilong.com/house/archives/hdu-5306-gorgeous-sequence/ Gorgeous Sequence Time Limit: 6 ...

  7. HDU 5860 Death Sequence(死亡序列)

    p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: Calibri; font-s ...

  8. HDU 1711 Number Sequence(数列)

    HDU 1711 Number Sequence(数列) Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Ja ...

  9. HDU 1005 Number Sequence(数列)

    HDU 1005 Number Sequence(数列) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Jav ...

随机推荐

  1. [ios] 微信订阅号: ios博文精选

    晚上下班后时间充裕,平时要么看电视剧,要么玩游戏 感觉浪费时间.  最后决定自己也搞一个微信订阅号分享技术方面的东西,也提升自己. 如果大家也是一样情况,欢迎大家关注我的订阅号. 微信订阅号: ios ...

  2. [ios2] CABasicAnimation【转】

    caanimation 整理了解  http://geeklu.com/2012/09/animation-in-ios/ 几个可以用来实现热门APP应用PATH中menu效果的几个方法 +(CABa ...

  3. [翻译]Eureka一窥

    什么是Eureka? Eureka是一个基于REST的服务,主要用在AWS云环境作为服务发现,负载均衡和失败转移.我们叫这个服务,Eureka服务. Eureka也有一个JAVA客户端组件, Eure ...

  4. jsp-1 简单的应用servlet,并用其跳转页面

    jspweb里面用到的servlet跳转页面的方法 使用的jar包只有 commons-lang3-3.5.jar 运行时,tomcat会先根据web.xml里面的信息,查找servlet <? ...

  5. ipad 横屏 竖屏 CSS

    /* iPads (landscape) ----------- */ @media only screen and (min-device-width : 768px) and (max-devic ...

  6. 【完全背包】HDU 4508 湫湫系列故事——减肥记I

    Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other) Total Submission(s) ...

  7. 修改html 属性,css样式。

    一 通过修改标签属性来改变它的样式  js设置和获取标签的属性 <script type="text/javascript"> window.onload = func ...

  8. nyoj 592 spiral grid(广搜)

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=592 解决以下问题后就方便用广搜解: 1.将数字坐标化,10000坐标为(0,0),这样就 ...

  9. lua中string常用api

    local a="abcdefgbbb" string.sub(a,1,3) 字符串截取 返回截取的字符串           print(string.sub(a,1,3))   ...

  10. FZU 2089 数字游戏

    Problem 2089 数字游戏  Problem Description 现在,给你2个整形数字A和B.你的任务就是计算出A+B的结果C后,统计C中数字5出现的次数.  Input 输入数据第一行 ...