思路:

(是不是只有我作大死写了个分块)

up[i][j]表示从第i块开始到第j个位置 上升的最大值

down[i][j]同理

left_up[i]表示从第i块开始能够上升的最长长度

left_down[i]同理

right_up[i]表示从第i块结尾上升的最长长度

right_down[i]同理

然后就是各种恶心的分类讨论

(见代码吧,,,,,,)

嗯这道题还可以差分以后线段树维护>0的最长长度(左max 右max 区间max)

//By SiriusRen
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=,inf=0x3f3f3f3f;
int n,q,l,r,a[N],block[N],up[][N],down[][N],left_up[],left_down[],right_up[],right_down[];
int main(){
scanf("%d",&n);int Block=sqrt(n);
for(int i=;i<=n;i++)scanf("%d",&a[i]);
for(int i=;i<=n;i++)block[i]=(i-)/Block+;
for(int i=;i<=block[n];i++){
int temp_up=,temp_down=,f_up=,f_down=;
for(int j=lower_bound(block+,block++n,i)-block;j<=n;j++){
up[i][j]=max(up[i][j-],temp_up),down[i][j]=max(temp_down,down[i][j-]);
if(!f_down)left_down[i]=temp_down;
if(!f_up)left_up[i]=temp_up;
if(a[j+]>a[j])temp_up++,temp_down=,f_down=;
else if(a[j+]<a[j])temp_down++,temp_up=,f_up=;
else temp_up++,temp_down++;
}
}
for(int i=;i<=block[n];i++){
int temp=lower_bound(block+,block++n,i)-block,j=upper_bound(block+,block++n,i)-block-,temp_up=,temp_down=;
for(;block[j]==block[temp];j--){
right_up[i]=max(right_up[i],temp_up),right_down[i]=max(right_down[i],temp_down);
if(a[j-]>a[j])temp_up++,temp_down=-inf;
else if(a[j-]<a[j])temp_down++,temp_up=-inf;
else temp_up++,temp_down++;
}
}
scanf("%d",&q);
while(q--){
scanf("%d%d",&l,&r);
if(block[l]==block[r]){
int ans=;
int temp_up=,temp_down=;
for(int j=l;j<=r;j++){
ans=max(ans,max(temp_up,temp_down));
if(a[j+]>a[j])temp_up++,temp_down=;
else if(a[j+]<a[j])temp_down++,temp_up=;
else temp_up++,temp_down++;
}
printf("%d\n",ans);
}
else{
int L=block[l]+,ans=max(up[L][r],down[L][r]),temp_up=,temp_down=;
int beginL=lower_bound(block+,block++n,L)-block;
for(int j=l;j<beginL;j++){
ans=max(ans,max(temp_up,temp_down));
if(a[j+]>a[j])temp_up++,temp_down=;
else if(a[j+]<a[j])temp_down++,temp_up=;
else temp_up++,temp_down++;
}
if(a[beginL]>=a[beginL-]){
int tmpx=min(right_down[L-],beginL-l),tmpy=min(r-beginL+,left_up[L]);
ans=max(ans,tmpx+tmpy);
}
if(a[beginL]<=a[beginL-]){
int tmpx=min(right_up[L-],beginL-l),tmpy=min(r-beginL+,left_down[L]);
ans=max(ans,tmpx+tmpy);
}
printf("%d\n",ans);
}
}
}

最新文章

  1. css外边距margin
  2. iReport 下载地址
  3. iOS学习10之OC类和对象
  4. 【AT91SAM3S】建立基于SAM3S库的工程并点亮LED
  5. Leetcode#129 Sum Root to Leaf Numbers
  6. php使用phpmailer发送邮件
  7. [LeetCode] 30. Substring with Concatenation of All Words 解题思路 - Java
  8. Sublime 学习记录(三) Emmet 插件
  9. PHP使用文件流下载文件方法(附:解决下载文件内容乱码问题)
  10. postgresql 添加uuid扩展
  11. C#的Lock
  12. XMind 8 pro update 7激活方法
  13. Linux在VirtualBox的网络设置
  14. 图论分支-Tarjan初步-割点和割边
  15. DroneCI启用privileged
  16. Responsive响应式设计
  17. 什么叫做GNU
  18. 〖Windows〗三星(SAMSUNG)905S3G-K07 安装Windows 7 过程分享
  19. [LeetCode] 383. Ransom Note_Easy tag: Hash Table
  20. xshell评估过期解决办法

热门文章

  1. SiftGPU:编译SiftGPU出现问题-无法解析的外部符号 glutInit
  2. 蛮好用的局域网测试工具iperf
  3. 11.03 在外链接中用OR逻辑
  4. Java中Json的用法
  5. redis客户端连接到服务器的步骤
  6. tomcat实现连接数据库
  7. BPM结束任务
  8. Django F查询Q查询Only与Defel
  9. PAT_A1110#Complete Binary Tree
  10. appium分层自动化的封装