题目描述

  在放完棋子之后,$dirty$又开始了新的游戏。
  现在他拥有一个长为$n$的数组$A$,他定义第$i$个位置的分值为$i−k+1$,其中$k$需要满足:
  对于任意满足$k\leqslant j\leqslant i$的$j$,有$A[k]\leqslant A[j]\leqslant A[i]$。当对于第$i$个数,有多个$k$满足条件时,取能获得较大分值的$k$。
  现在,$dirty$想要知道$A$数组中分值最大的位置对应的分值为多少。


输入格式

第一行一个整数$n$,表示$A$数组的长度。
第二行$n$个整数,第$i$个数表示$A[i]$的值。


输出格式

输出一行一个整数,表示$A$数组中分值最大的位置对应的分值。


样例

样例输入:

8
8 6 1 7 9 2 3 8

样例输出:

3


数据范围与提示

注意由于$n$的范围较大,本题可能需要使用更快的读入方法。

对于$10\%$的数据,$n\leqslant 10^3$;
对于$40\%$的数据,$n\leqslant 3\times 10^5$;
对于另外$20\%$的数据为随机数据,且$n\leqslant 10^6$;
对于$100\%$的数据,$1\leqslant n\leqslant 10^7$;$1\leqslant A[i]\leqslant 10^9$。


题解

先来解释一下题意,对于区间$[k,i]$,我们只用保证中间的所有元素都大于等于$A[k]$,比小于等于$A[i]$即可,而不用关注其内部大小关系。

分值越大意味着$k$越小。

接下来说一下我考场上的思路,发现对于每一个$i$其最小的$k$位于其前面最后一个比它大的数之间最小的数,也就是如下图$\downarrow$

那么我们可以用单调栈维护第一个比它大的,然后用线段树查询区间最小值的位置即可,然后它就$\downarrow$

这个思路最傻的地方在于为何不用单调栈在维护一个最小值……

时间复杂度:$\Theta(n)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

$60\%$算法:

  1. #include<bits/stdc++.h>
  2. #define int int_least32_t
  3. #define L(x) x<<1
  4. #define R(x) x<<1|1
  5. using namespace std;
  6. const int L=1<<20|1;
  7. char buffer[L],*S,*T;
  8. #define inline __attribute__((optimize("-O3")))
  9. #define getchar() ((S==T&&(T=(S=buffer)+fread(buffer,1,L,stdin),S==T))?EOF:*S++)
  10. int n;
  11. int a[10000010];
  12. int ans;
  13. int trmin[40000010],pmin[40000010];
  14. int sta[10000010],top;
  15. inline int read(){
  16. int ss(0);char bb(getchar());
  17. while(bb<48||bb>57)bb=getchar();
  18. while(bb>=48&&bb<=57)ss=(ss<<1)+(ss<<3)+(bb^48),bb=getchar();
  19. return ss;
  20. }
  21. inline void pushup(int x)
  22. {
  23. if(trmin[L(x)]<=trmin[R(x)])
  24. {
  25. trmin[x]=trmin[L(x)];
  26. pmin[x]=pmin[L(x)];
  27. }
  28. else
  29. {
  30. trmin[x]=trmin[R(x)];
  31. pmin[x]=pmin[R(x)];
  32. }
  33. }
  34. inline void build(int x,int l,int r)
  35. {
  36. if(l==r){trmin[x]=a[l];pmin[x]=l;return;}
  37. int mid=(l+r)>>1;
  38. build(L(x),l,mid);
  39. build(R(x),mid+1,r);
  40. pushup(x);
  41. }
  42. inline pair<int,int> askmin(int x,int l,int r,int L,int R)
  43. {
  44. if(r<L||R<l)return make_pair(-0x3f3f3f3f,0x3f3f3f3f);
  45. if(L<=l&&r<=R)return make_pair(pmin[x],trmin[x]);
  46. int mid=(l+r)>>1;
  47. pair<int,int> lft=askmin(L(x),l,mid,L,R);
  48. pair<int,int> rht=askmin(R(x),mid+1,r,L,R);
  49. return lft.second<=rht.second?lft:rht;
  50. }
  51. int main()
  52. {
  53. n=read();
  54. for(int i=1;i<=n;i++)a[i]=read();
  55. a[n+1]=0x3f3f3f3f;
  56. build(1,1,n+1);
  57. for(int i=1;i<=n;i++)
  58. {
  59. while(top&&a[sta[top]]<=a[i])top--;
  60. int flag=sta[top]+1;
  61. sta[++top]=i;
  62. if(i-flag<ans)continue;
  63. pair<int,int> minn=askmin(1,1,n+1,flag,i);
  64. ans=max(ans,i-minn.first+1);
  65. }
  66. printf("%d",ans);
  67. return 0;
  68. }

$100\%$算法:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. int n;
  4. int a[10000001],sta[10000001],maxn[10000001];
  5. int ans;
  6. int main()
  7. {
  8. scanf("%d",&n);
  9. for(int i=1;i<=n;i++)scanf("%d",&a[i]);
  10. for(int i=1;i<=n;i++)
  11. {
  12. while(sta[0]&&a[i]<a[sta[sta[0]]])
  13. {
  14. if(a[maxn[sta[0]-1]]<=a[maxn[sta[0]]])maxn[sta[0]-1]=maxn[sta[0]];
  15. ans=max(ans,maxn[sta[0]]-sta[sta[0]]+1);
  16. maxn[sta[0]--]=0;
  17. }
  18. sta[++sta[0]]=i;
  19. maxn[sta[0]]=i;
  20. }
  21. while(sta[0])
  22. {
  23. if(a[maxn[sta[0]-1]]<=a[maxn[sta[0]]])maxn[sta[0]-1]=maxn[sta[0]];
  24. ans=max(ans,maxn[sta[0]]-sta[sta[0]]+1);
  25. maxn[sta[0]--]=0;
  26. }
  27. printf("%d",ans);
  28. return 0;
  29. }

rp++

[CSP-S模拟测试]:array(单调栈)的更多相关文章

  1. Educational Codeforces Round 23 D. Imbalanced Array 单调栈

    D. Imbalanced Array time limit per test 2 seconds memory limit per test 256 megabytes input standard ...

  2. AtCoder Grand Contest 005【A栈模拟,B单调栈】

    挖草,AtCoder实在是太吊了~ %%%,目前只A了两题: A题: 就是利用栈模拟一下就好了:S进栈,T的话有S就出栈,然后len减一下就好了: #include <bits/stdc++.h ...

  3. 「10.11」chess(DP,组合数学)·array(单调栈)·ants(莫队,并茶几)

    菜鸡wwb因为想不出口胡题所以来写题解了 A. chess 昨天晚上考试,有点困 开考先花五分钟扫了一边题,好开始肝$T1$ 看了一眼$m$的范围很大,第一反应矩阵快速幂?? $n$很小,那么可以打$ ...

  4. 【单调栈】Vijos P1926 紫色的手链

    题目链接: https://vijos.org/p/1926 题目大意: 给n个数(n<=100 000),求任意区间的最大值异或次大值的最大值. 题目思路: [模拟][单调栈] 我们维护一个严 ...

  5. [CSP-S模拟测试]:导弹袭击(数学+凸包+单调栈)

    题目背景 $Guess$准备向敌军阵地发起进攻了!$Guess$的武器是自动制导导弹.然而在机房是不允许游戏的,所以班长$XZY$对游戏界面进行了降维打击,结果... 题目描述 众所周知,环境因素对导 ...

  6. [CSP-S模拟测试]:A(单调栈维护凸包+二分答案)

    题目传送门(内部题150) 输入格式 第一行两个整数$N,Q$. 接下来的$N$行,每行两个整数$a_i,b_i$. 接下来的$Q$行,每行一个整数$x$. 输出格式 对于每个询问,输出一行一个整数表 ...

  7. [CSP-S模拟测试]:Cover(单调栈++单调队列+DP)

    题目传送门(内部题126) 输入格式 第一行两个个整数$n,m$表示区间的长度与彩灯的数量. 接下来$m$行,每行三个整数$l_i,r_i,a_i$表示一条彩灯能够覆盖的区间以及它的美观程度. 输出格 ...

  8. [CSP-S模拟测试]:你相信引力吗(单调栈)

    题目传送门(内部题124) 输入格式 第一行一个整数$n$代表环的长度. 第二行$n$个整数表示每个冰锥的高度. 输出格式 一行一个整数表示有多少对冰锥是危险的. 样例 样例输入1: 51 2 4 5 ...

  9. [CSP-S模拟测试]:陶陶摘苹果(线段树维护单调栈)

    题目传送门(内部题116) 输入格式 第一行两个整数$n,m$,如题 第二行有$n$个整数表示$h_1-h_n(1\leqslant h_i\leqslant 10^9)$ 接下来有$m$行,每行两个 ...

随机推荐

  1. 磁盘管理|df、du|分区 fdisk |格式化

    3.磁盘管理 3.1命令df ·用于查看已挂载磁盘的总容量,使用容量,剩余容量等. -i:查看inodes的使用情况 -h:使用合适的单位显示 -k:以KB为单位显示 -m:以MB为单位显示 3.1. ...

  2. Intersection of Two Arrays(交集)

    来源:https://leetcode.com/problems/intersection-of-two-arrays Given two arrays, write a function to co ...

  3. 【转】mysqldump原理探究

    作者:胡儿胡儿 来源:CSDN 原文:https://blog.csdn.net/cug_jiang126com/article/details/49824471 —————————————————— ...

  4. 替换url不刷新页面

    今天碰到一个有趣的问题, 从其他站点登录后,放回了一个token, 但是我切换了路由之后token还在, 路由直接跟在了token参数后面, 后面先利用location.href替换掉原来的连接, 但 ...

  5. numpy数组的运算

    numpy数组的运算 数组的乘法 >>> import numpy as np >>> arr=np.array([[1,2,3],[4,5,6]]) >&g ...

  6. HDU1688-POJ3463-Sightseeing(求次短路的条数)

    题意 求出最短路和次短路的条数,当次短路比最短路长度小1时,输出条数之和,反之输出最短路条数. 题解  dis1[],cnt1[],dis2[],cnt2[] 分别表示最短路的长度和条数,次短路的长度 ...

  7. activemq高可用

    这里是基于 zookeeper 选举方式实现的集群配置,服务器过半数才可提供服务,所以是2n+1台这里以三台为例. 只有master节点能提供服务,slave节点无法提供服务,只有当master节点挂 ...

  8. C#GC垃圾回收和析构函数和IDisposable的使用

    一,什么是GC 1,GC是垃圾回收器,一般来说系统会自动检测不会使用的对象或变量进行内存的释放,不需要手动调用,用Collect()就是强制进行垃圾回收,使内存得到及时的释放,让程序效率更高. 2,G ...

  9. java体系中OOP,OOD,OOA分别代表什么含义,以及OA,CRM,ERP

    OOP:Object Oriented Programming 面向对象程序设计. OOD:Object Oriented Design 面向对象设计. OOA:Object Oriented Ana ...

  10. how to install protobuff python

    当前环境: operate system: Ubuntu 14.04.1 LTS protoc --version: libprotoc 2.5.0    protocol-buffers versi ...