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 ...
随机推荐
- list、dict、tuple的一些小操作总结
一.list 1.赋值(append) list.append(data) 2.去重 list(set(list)) list_gpcode = list(set(list(dfQuery.index ...
- 【C#】Send data between applications
This sample shows how to send data between different applications, including object data——transform ...
- 竞争激烈的洗衣O2O
今日,洗衣O2O干洗客宣布已获得千万美金Pre-A轮融资,投资方为新加坡某资本,具体信息尚不便透露. “干洗客”是36氪此前报道过的洗衣O2O服务商,2013年7月诞生于上海,2014年12月经历重组 ...
- flexbox备忘
伸缩项目的父元素: display:flex || display:inline-flex fiex-direction: row(默认) | row-reverse | column | colum ...
- GridView”的控件 必须放在具有 runat=server 的窗体标记内 “错误提示”
在做导出数据到EXCEL程序中,出现了错误提示:类型“GridView”的控件“GridView1”必须放在具有 runat=server 的窗体标记 解决办法 重写 VerifyRendering ...
- c#计算datatable中某一列值的和
double sumPercentage = dt.AsEnumerable().Where(dr => { return dt.Rows.IndexOf(dr) > 0; }).Sum( ...
- 动态网站加速,cdn义不容辞
"双十一"大战已经落下帷幕,各大电商纷纷拿出了亮眼的成绩单,但在这些成绩单的背后,CDN加速技术是功不可没的.随着互联网的发展,电商.视频直播等网站的火热,以及各个云加速平台的流行 ...
- 在2002年的老电脑上安装Debian
在2002年自己花了家里八千多元买了一台联想昭笔记本电脑.配置是PIII 750 Hz, 128 MB内存(后来升级到了320 MB).那个时候大学里买笔记本电脑的人还不多,宿舍里的同学大都攒的台式机 ...
- svn客户端的安装与中文版本语言库
首先在mac下下载svn或者其他软件请看另一篇博客链接:http://www.cnblogs.com/minyc/p/myc201606191543.html 另附svn常用命令操作详解:http:/ ...
- CSS3 六边形绘制
把一个104px的div放在它们之间,设置一个背景颜色: width: 0; border-bottom: 30px solid #6C6; border-left: 52px solid trans ...