UVA 12697 Minimal Subarray Length

Minimal Subarray Length

Time Limit: 3000ms

Memory Limit: 131072KB

This problem will be judged on UVALive. Original ID: 6609
64-bit integer IO format: %lld      Java class name: Main

You are given an integer sequence of length N and another value X. You have to find a contiguous subsequence of the given sequence such that the sum is greater or equal to X. And you have to find that segment with minimal length.

Input

First line of the input file contains T the number of test cases. Each test case starts with a line containing 2 integers N (1 ≤ N ≤ 500000) and X (−109 ≤ X ≤ 109). Next line contains N integers denoting the elements of the sequence. These integers will be between −109 to 109 inclusive.

Output

For each test case output the minimum length of the sub array whose sum is greater or equal to X. If there is no such array, output ‘-1’.

Sample Input

3
5 4
1 2 1 2 1
6 -2
-5 -6 -7 -8 -9 -10
5 3
-1 1 1 1 -1

Sample Output

3
-1
3

解题:先求和。维护一个队列,下标单调,值也单调。对于i,j.如果sum[i] <= sum[j] && i > j ,那么i肯定比j好。去掉j.

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 #include <climits>
 7 #include <vector>
 8 #include <queue>
 9 #include <cstdlib>
10 #include <string>
11 #include <set>
12 #include <stack>
13 #define LL long long
14 #define pii pair<int,int>
15 #define INF 0x3f3f3f3f
16 using namespace std;
17 const int maxn = 500100;
18 LL sum[maxn] = {0};
19 int n,x,inc[maxn];
20 int main() {
21     int t,i,lt,rt,ans;
22     scanf("%d",&t);
23     while(t--){
24         scanf("%d %d",&n,&x);
25         for(i = 1; i <= n; i++){
26             scanf("%lld",sum+i);
27             sum[i] += sum[i-1];
28         }
29         lt = 0;
30         inc[0] = rt = 1;
31         ans = n+1;
32         for(i = 2; i <= n; i++){
33             while(lt < rt && sum[i] <= sum[inc[rt-1]]) rt--;
34             inc[rt++] = i;
35             while(lt + 1 < rt && sum[i] - sum[inc[lt]] >= x){
36                 ans = min(ans,i-inc[lt]);
37                 lt++;
38             }
39         }
40         ans == n+1?puts("-1"):printf("%lld\n",ans);
41     }
42     return 0;
43 }

时间: 2024-08-09 06:45:31

UVA 12697 Minimal Subarray Length的相关文章

UVALive 6609(Minimal Subarray Length)维护递增序列|RMQ

题意:给一个整数序列(可能有负数),求最短的连续序列使得序列之和大于等于整数x: 解法:第一种是On的复杂度: 我们要的是sum[j]-sum[i]>=x,如果有两个决策j < j',而且sum[j] >= sum[j'],那么j就是没用的.即维护一个sum[j]递增序列.然后每次可以二分查找,但是这里有个特点就是要得到最近的,可以同时维护一个left指针,left指针用于跟进更行答案的左边界,因为维护的单调栈不会再右移到left左边去了(因为如果left右边还可以更新的答案肯定没有当前

UVALive 6609 Minimal Subarray Length(RMQ-ST+二分)

题意:给定长度为N的数组,求一段连续的元素之和大于等于K,并且让这段元素的长度最小,输出最小长度即可. 题目链接:UVAlive 6609 做法:做一个前缀和prefix,然后再作一个维护前缀和最大值数组Max,枚举所有可能的起始点i,在Max上二分末尾位置r,由于Max维护的是前缀和的最大值,因此具有单调性,可以进行二分,似乎还有其他O(n)的做法,有空去膜一下 代码: #include <stdio.h> #include <bits/stdc++.h> using names

uva 10020 Minimal coverage 【贪心】+【区间完全覆盖】

Minimal coverage The Problem Given several segments of line (int the X axis) with coordinates [Li,Ri]. You are to choose the minimal amount of them, such they would completely cover the segment [0,M]. The Input The first line is the number of test ca

UVA 10020 - Minimal coverage 解题心得

原题: The Problem Given several segments of line (int the X axis) with coordinates [Li,Ri]. You are to choose the minimal amount of them, such they would completely cover the segment [0,M]. The Input The first line is the number of test cases, followed

UVa 10020 - Minimal coverage(区间覆盖并贪心)

Given several segments of line (int the X axis) with coordinates [Li, Ri]. You are to choose the minimal amount of them, such they would completely cover the segment [0, M].InputThe first line is the number of test cases, followed by a blank line.Eac

【区间覆盖问题】uva 10020 - Minimal coverage

可以说是区间覆盖问题的例题... Note: 区间包含+排序扫描: 要求覆盖区间[s, t]; 1.把各区间按照Left从小到大排序,如果区间1的起点大于s,则无解(因为其他区间的左起点更大):否则选择起点在s的最长区间; 2.选择区间[li, ri]后,新的起点应更新为ri,并且忽略所有区间在ri之前的部分:  Minimal coverage  The Problem Given several segments of line (int the X axis) with coordinat

uva 10020 Minimal coverage(贪心,区间覆盖)

这道题一读就是经典的区间问题,是区间覆盖,敲过之后还有花了很长的调试时间,还是我不熟练,现在做题确实挺慢 的,简单题目也要做好久,没事,慢慢来.最重要的要确保正确率和心态问题,认真对待,调试找到了好多bug,一些 细节问题...都是刚开始没有注意到的.交了之后RE,在数组上多加了两个0.A了,,uva老是不提示数据有多大, 所以只能乱开... 思路: 先对区间按左边的点进行排序,如果当前需要涵盖的区间为[x,y],那么在排序的区间中到左边小于x,右 边最大的那个区间,设为Max,然后更新想找的区

uva 11536 - Smallest Sub-Array

题目大意:按照题目中的要求构造出一个序列,找出最短的子序列,包含1~k. 解题思路:先根据题目的方法构造出序列,然后用Towpointer的方法,用v[i]来记录当前[l, r]中有几个i:当r移动时,出现v[i] == 1时, c++(用来记录有几个1~k的数字):当c == k 时,就要移动l,当出现v[i] == 0时,c--. 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #in

UVa 10020 Minimal coverage

题意是:输入几个样例,每个样例第一行输入从0开始需要覆盖的长度M,即[0,M].之后输入覆盖的线段,求需要的线段条数最小值. 思路:贪心算法,具体见代码及注释. #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <algorithm> using namespace std; #define MAXN 100001 /*将输入数