UVALive_6609_Minimal Subarray Length(RMQ+二分)
2014-11-18 19:50
459 查看
题型:数据结构
题意:在n个数中求出最短连续序列,是的序列之和大于等于X。
分析:
一开始想是单调队列,或者单纯的二分,但是由于数据有正有负,所以其前缀和sum数组并没有单调性,所以这个方法不行。
后来想到,对sum数组,要求有这样的解,sum[j] - sum[i] ≥ x
枚举起点i,然后二分区间[i+1,n],每次用l到mid之间的sum最大值减去sum[i]看是否≥ x。
如果成立,说明左区间存在答案,那么往左边二分;
如果不成立,就是说连左区间的最大值都不能满足答案,那么左区间根部不存在答案,那么就往右区间二分。
然后更新最短长度的答案。
复杂度O(nlog(n))
代码:
题意:在n个数中求出最短连续序列,是的序列之和大于等于X。
分析:
一开始想是单调队列,或者单纯的二分,但是由于数据有正有负,所以其前缀和sum数组并没有单调性,所以这个方法不行。
后来想到,对sum数组,要求有这样的解,sum[j] - sum[i] ≥ x
枚举起点i,然后二分区间[i+1,n],每次用l到mid之间的sum最大值减去sum[i]看是否≥ x。
如果成立,说明左区间存在答案,那么往左边二分;
如果不成立,就是说连左区间的最大值都不能满足答案,那么左区间根部不存在答案,那么就往右区间二分。
然后更新最短长度的答案。
复杂度O(nlog(n))
代码:
#include<cstdio> #include<algorithm> using namespace std; typedef long long LL; const LL inf=0x3f3f3f3f3f3f3f3fLL; const int M=5e5+10; class Range_Maximum_Query{ int LOG[M]; LL dpmax[M][20],dpmin[M][20]; public: void init(){ LOG[0]=-1; for(int i=1;i<M;i++){ LOG[i]=LOG[i>>1]+1; } } void Make_RMQ(int n,LL a[]){ for(int i=1;i<=n;i++){ dpmax[i][0]=dpmin[i][0]=a[i]; } for(int j=1;j<=LOG ;j++){ for(int i=1;i+(1<<j)-1<=n;i++){ dpmax[i][j]=max(dpmax[i][j-1],dpmax[i+(1<<(j-1))][j-1]); dpmin[i][j]=min(dpmin[i][j-1],dpmin[i+(1<<(j-1))][j-1]); } } } LL get_RMQ(int a,int b,bool big){ int k=LOG[b-a+1]; if(big) return max(dpmax[a][k],dpmax[b-(1<<k)+1][k]); return min(dpmin[a][k],dpmin[b-(1<<k)+1][k]); } }rmq; LL a[M],sum[M]; int main(){ int t,n,m; rmq.init(); while(~scanf("%d",&t)){ while(t--){ scanf("%d%d",&n,&m); sum[0]=0; for(int i=1,in;i<=n;i++){ scanf("%d",&in); a[i]=in; sum[i]=sum[i-1]+a[i]; } rmq.Make_RMQ(n,sum); int ans=0x3f3f3f3f; for(int i=1;i<=n;i++){ int L=i,R=n; while(L<=R){ int mid=(L+R)>>1; LL big=rmq.get_RMQ(i,mid,1); if(big-sum[i-1]>=m){ ans=min(ans,mid-i+1); R=mid-1; } else{ L=mid+1; } } } if(ans==0x3f3f3f3f) ans=-1; printf("%d\n",ans); } } return 0; }
相关文章推荐
- UVALive 6609 Minimal Subarray Length rmq+二分or单调队列
- UVALive 6609(Minimal Subarray Length)维护递增序列|RMQ
- uvalive 6609 - Minimal Subarray Length(离散化+树状数组)
- UVALive 6609 Minimal Subarray Length(最大子段)
- [J - Minimal Subarray Length UVALive - 6609] 区间问题
- 【单调栈思路】Minimal Subarray Length UVALive - 6609
- Uva 6609 - Minimal Subarray Length(RMQ)
- UVALive 6609 Minimal Subarray Length (查找+构建排序数组)
- UVALive 6609 Minimal Subarray Length (查找+构建排序数组)
- HOJ 13006 Minimal Subarray Length (单调队列或RMQ加二分)
- LA 6609 - Minimal Subarray Length
- UVA 12697 Minimal Subarray Length
- UVALive - 3635 - Pie(二分)
- UVALive - 3268 Jamie's Contact Groups(二分+最大流)
- UVALive 6902 Three Squares(二分 + 搜索)
- 例题1.13 派 Pie UVALive - 3635 二分
- 【二分匹配】 UVALive 6525 Attacking rooks
- UVALIVE 3525 Wild West <分类枚举 + 二分优化>
- UVALive 6656 Watching the Kangaroo --二分
- UVAlive--4529--Dangerous Tunnels(二分+拆点最大流)