Description

Tz又耍畸形了!!他要当飞行员,他拿到了一个飞行员测试难度序列,他设定了一个难度差的最大值,在序列中他想找到一个最长的子串,任意两个难度差不会超过他设定的最大值。耍畸形一个人是不行的,于是他找到了你。

Input

输入:第一行两个有空格隔开的整数k(0<=k<=2000,000,000),n(1<=n<=3000,000),k代表Tz设定的最大值,n代表难度序列的长度。第二行为n个由空格隔开的整数ai(1<=ai<=2000,000,000),表示难度序列。

Output

输出:最大的字串长度。

Sample Input

3 9

5 1 3 5 8 6 6 9 10

Sample Output

4

(有两个子串的长度为4: 5, 8, 6, 6 和8, 6, 6, 9.最长子串的长度就是4)

Solution

枚举每个点,看以它作为右端点的最优答案是什么

考虑一个区间,我们其实只需要看最大值和最小值

如果它们的差不满足要求,那最大值和最小值肯定要走一个,从区间里踢掉,\(l\) 指针肯定要往右走。假设最大值的位置是 \(i\) ,最小值的位置是 \(j\) ,那么 \(l\) 指针贪心地走到 \(min(i,j)+1\) 的位置,接着再看区间的最大最小值是否满足要求

最大值最小值会改变,于是就拿两个单调队列维护单调递增和单调递减,这样踢掉一个最值后,可以马上知道下一个最值

那这个是 \(n^2\) 的,因为每次枚举的点都要从头开始考虑

但我们发现,右端新加进来一个点对于左边不断踢点是没有影响的。右端加进来一个点,不可能会使最优区间的 \(l\) 还往左走

所以不需要每个点都从头考虑,直接一遍扫过去然后不停加点就行了

#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
const int MAXN=3000000+10;
int n,k,A[MAXN],ans,ps=1;
std::deque<int> q1,q2;
template<typename T> inline void read(T &x)
{
T data=0,w=1;
char ch=0;
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
x=data*w;
}
template<typename T> inline void write(T x,char ch='\0')
{
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
if(ch!='\0')putchar(ch);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
int main()
{
read(k);read(n);
for(register int i=1;i<=n;++i)
{
read(A[i]);
while(!q1.empty()&&A[i]>=A[q1.back()])q1.pop_back();
while(!q2.empty()&&A[i]<=A[q2.back()])q2.pop_back();
q1.push_back(i);q2.push_back(i);
while(A[q1.front()]-A[q2.front()]>k)
if(q1.front()<q2.front())ps=q1.front()+1,q1.pop_front();
else ps=q2.front()+1,q2.pop_front();
chkmax(ans,i-ps+1);
}
write(ans,'\n');
return 0;
}

写了单调队列后,发现二分+ST表好像也可以做,二分区间的长度, \(O(n)\) 枚举左端点,用ST表找最值,看它们的差是否满足要求

然后写了一下,交一发,结果,卡空间?洛谷RE,BZOJ直接TLE(而且还是只测了1s不到,就直接变成30sTLE,什么操作?)

所以这个东东就当好玩吧,也没去调细节了

#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
const int MAXN=3000000+10;
int n,k,A[MAXN],g[MAXN],Mx[MAXN][24],Mn[MAXN][24];
template<typename T> inline void read(T &x)
{
T data=0,w=1;
char ch=0;
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
x=data*w;
}
template<typename T> inline void write(T x,char ch='\0')
{
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
if(ch!='\0')putchar(ch);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
inline void init()
{
for(register int i=1;i<=n;++i)g[i]=(int)log2(i);
for(register int j=1;j<=22;++j)
for(register int i=1;i+(1<<j)-1<=n;++i)
{
Mx[i][j]=max(Mx[i][j-1],Mx[i+(1<<j-1)][j-1]);
Mn[i][j]=min(Mn[i][j-1],Mn[i+(1<<j-1)][j-1]);
}
}
inline int calc(int l,int len)
{
int r=l+len-1,k=g[len];
return max(Mx[l][k],Mx[r-(1<<k)+1][k])-min(Mn[l][k],Mn[r-(1<<k)+1][k]);
}
inline bool check(int len)
{
for(register int i=1;i+len-1<=n;++i)
if(calc(i,len)<=k)return true;
return false;
}
int main()
{
read(k);read(n);
for(register int i=1;i<=n;++i)
{
read(A[i]);
Mx[i][0]=Mn[i][0]=A[i];
}
init();
int l=1,r=n,ans=1;
while(l<=r)
{
int mid=(l+r)>>1;
if(check(mid))ans=mid,l=mid+1;
else r=mid-1;
}
write(ans,'\n');
return 0;
}

【刷题】BZOJ 2096 [Poi2010]Pilots的更多相关文章

  1. BZOJ 2096: [Poi2010]Pilots( set )

    用个set维护就可以水过去...O(NlogN) 应该可以用单调队列O(N).... --------------------------------------------------------- ...

  2. BZOJ 2096: [Poi2010]Pilots

    Description 求一个最长的序列,最大值最小值之差不超过 \(k\) . Sol 单调队列. 一个队列直接上就行.. Code /******************************* ...

  3. BZOJ——2096: [Poi2010]Pilots

    http://www.lydsy.com/JudgeOnline/problem.php?id=2096 Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: ...

  4. BZOJ 2096: [Poi2010]Pilots 单调队列

    Code: #include<bits/stdc++.h> #define maxn 4000000 using namespace std; void setIO(string s) { ...

  5. BZOJ 2096([Poi2010]Pilots-单调队列-差值)

    2096: [Poi2010]Pilots Time Limit: 30 Sec   Memory Limit: 162 MB Submit: 190   Solved: 97 [ Submit][ ...

  6. bzoj2096[Poi2010]Pilots 单调队列

    2096: [Poi2010]Pilots Time Limit: 30 Sec  Memory Limit: 162 MBSubmit: 983  Solved: 513[Submit][Statu ...

  7. 【刷题】BZOJ 2407 探险

    Description 探险家小T好高兴!X国要举办一次溶洞探险比赛,获奖者将得到丰厚奖品哦!小T虽然对奖品不感兴趣,但是这个大振名声的机会当然不能错过! 比赛即将开始,工作人员说明了这次比赛的规则: ...

  8. 【刷题】BZOJ 4543 [POI2014]Hotel加强版

    Description 同OJ3522 数据范围:n<=100000 Solution dp的设计见[刷题]BZOJ 3522 [Poi2014]Hotel 然后发现dp的第二维与深度有关,于是 ...

  9. 【刷题】BZOJ 4316 小C的独立集

    Description 图论小王子小C经常虐菜,特别是在图论方面,经常把小D虐得很惨很惨. 这不,小C让小D去求一个无向图的最大独立集,通俗地讲就是:在无向图中选出若干个点,这些点互相没有边连接,并使 ...

随机推荐

  1. 「日常训练」The Necklace(UVA-10054)

    代码 for(int i=0; i!=n; ++i) { int u = cin.nextInt(); int v = cin.nextInt(); edges.add(new Edge(u,v)); ...

  2. Git生成SSH密钥

    git config --global user.name "yangjianliang"配置用户名 git config --global user.email "52 ...

  3. Winrar去广告图文教程

    一.前言 1.1 Winrar 解压缩工具 市场上有很多优秀的压缩工具,常用的有Winrar 和360 压缩工具.Winrar是免费压缩工具,特色是每次使用都会弹出广告.影响用户体验和工作效率,当然最 ...

  4. Spring学习(3):IOC基础(转载)

    一. IoC是什么 Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想.在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象 ...

  5. DNS递归查询与迭代查询

    注:一般TCP/IP的应用层或者OSI的会话.表示.应用层把数据称为数据或者信息,到了传输层把数据称为报文,到了最底层就是比特流了也就是字节流 DNS递归查询与迭代查询   基础知识 1.域名系统 2 ...

  6. cmake-index-3.11.4机翻

    index next | CMake » git-stage git-master latest release 3.13 3.12 3.11.4 3.10 3.9 3.8 3.7 3.6 3.5 3 ...

  7. .NET导出Excel之NPOI

    前段时间研究过微软的Excel导出.table输出Excel,而它们也存在一些弊端: 1.对于微软的Excel导出存在一些弊端,如:需要安装Office软件.速度问题: 2.table输出Excel在 ...

  8. .net组件和com组件&托管代码和非托管代码

    com组件和.net组件: COM组件是非托管对象,可以不需要.NET框架而直接运行,.NET框架组件是托管对象,必须有.NET框架的支撑才能运行. COM组件有独立的类型库文件,而.NET组件是通过 ...

  9. equals()和hashcode()详解

    转载自http://www.cnblogs.com/Qian123/p/5703507.html java.lang.Object类中有两个非常重要的方法:   public boolean equa ...

  10. 3.结对编程成果报告(小学生四则运算的出题程序,Java实现)

    程序名称:小学生四则运算的出题程序 先附上代码: package com.makequestion; import java.text.DecimalFormat;import java.util.R ...