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. SRM 563 500pts SpellCards

    SpellCards 题意: 有n张符卡排成一个队列,每张符卡有两个属性,等级li和伤害di. 两种操作: 1.把队首的符卡移动到队尾:2.使用队首的符卡,对敌人造成di点伤害,并丢弃队首的li张符卡 ...

  2. idea 从javadoc中复制内容出来

    打开 tool window就行了 经验:百度google不到的东西太多了,要学会自己想办法,至少也要把功能都试一遍吧, 而且像这种东西官方一般会给方法实现你的目的,只不过有时候是把功能迁移了或者整合 ...

  3. Zigbee系列(概览)

    Zigbee技术特点 低速率: 数据传输速率只有20~250kb/s, 2.4GHZ提供250kb/s, 915MHz对应40kb/s, 868Mhz对应20kb/s 低功耗:睡眠模式设备使用电池供电 ...

  4. C/C++ 下mysql应用封装(连接增删改查)

    mysql - 初始化 1) mysql_init():初始化数据库 2) mysql_real_connect()(不推荐用Mysql_connect()):连接数据库 详细代码如下: bool d ...

  5. Selenium自动化测试第二天(上)

    如有任何学习问题,可以添加作者微信:lockingfree 目录 Selenium自动化测试基础 Selenium自动化测试第一天(上) Selenium自动化测试第一天(下) Selenium自动化 ...

  6. AnyProxy对搜狐汽车app抓包

    关于AnyProxy 详细文档链接 http://anyproxy.io/cn/ anyproxy流程图 简要描述 当http请求经过代理服务器时,具体处理过程是: 收集请求所有请求参数,包括meth ...

  7. Unity Lighting - Reflections 反射(六)

      Reflections 反射 Reflection Source 反射源 By default, objects in a scene are rendered using Unity’s ‘St ...

  8. 《图解 HTTP 》阅读 —— 第三章

    第3章 HTTP 报文内的 HTTP 信息 用于 HTTP 协议交互的信息称为 HTTP 报文:请求报文和响应报文 HTTP 在传输数据时通过编码可以提升速率,能有效的处理大量数据,但是会消耗更多的C ...

  9. Numpy入门笔记第二天

    # 数组的组合 import numpy as np arr1 = np.arange(5) arr2 = np.arange(3) print arr1 print arr2 [0 1 2 3 4] ...

  10. Python3实现机器学习经典算法(三)ID3决策树

    一.ID3决策树概述 ID3决策树是另一种非常重要的用来处理分类问题的结构,它形似一个嵌套N层的IF…ELSE结构,但是它的判断标准不再是一个关系表达式,而是对应的模块的信息增益.它通过信息增益的大小 ...