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 ...
随机推荐
- Js-Html 前端系列--点击非Div区域隐藏Div
最近做项目要用到三字码下拉,调用一个插件,但是滚动条不能点击. 后来看另一个插件后突发奇想,在点击其他区域的时候隐藏这个Div就可以了. 背景:输入文字,弹出下拉Div,点击或者拉动Div滚动条选择, ...
- HttpContext.Current.Request.ServerVariables
Request.ServerVariables("Url") 返回服务器地址Value 0: /WebSite1/Default.aspx Request.ServerVariab ...
- C#开发学习——常用的正则表达式
对于想学习正则表达式的童鞋,一些基础的语法啥的,可以参考 http://www.cnblogs.com/China3S/archive/2013/11/30/3451971.html 下边是一些我们常 ...
- JavaScript中遍历数组 最好不要使用 for in 遍历
先看一段代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...
- 证据权模型(C#版)
证据权法是通过计算和利用各种不同证据的权重(表示相对重要性)并将多种证据结合起来,预测某个时间是否会发生的一种方法 证据权法以概率论中的贝叶斯定理为基础.设D表示要一个随机事件.用P(D)表示这一事件 ...
- 关于【IE兼容】的都在这
滚动条 ie的滚动条覆盖了内容,为了触屏操作优化浏览器的内容显示,IE 浏览器提供了一种可以浮动显示,自动隐藏的滚动条样式,但是这个样式会在某些情况下造成一些困扰,比如下图... 其实默认情况下,桌面 ...
- 在虚拟机上配置linux lab的相关经验
最近一直在研究怎样在嵌入式开发板上移植linux嵌入式系统,但是不太想花费太多钱购买开发板.然后在网上搜索相关的arm模拟器.有qemu,skyeye,armulator等,在按照网上教程一步一步实践 ...
- vlc-android1.8.0的全部源代码[包括C语言]
我们基于vlc,整理出了vlc-android1.8.0的全部源代码, 并增加了LibVLC的简单调用, 您只需要7行代码,就可以完成调用,和原生的MediaPlayer类似. 下载地址https:/ ...
- Java io流的概述
Java语言定义了许多专门负责各种方式的输入/输出,这些类都被放在java.io包中.其中,所有输入流类都是抽象类InputStream(字节输入流)或抽象类Reader(字符输入流)的子类:而所有输 ...
- magento表单的导出
1.Grid.php中得有: $this->addExportType('*/*/exportXml' , Mage::helper('hpusernetwork' )->__('Ex ...