UVALive 6609 Minimal Subarray Length(RMQ-ST+二分)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 namespace std; #define INF 0x3f3f3f3f #define LC(x) (x<<1) #define RC(x) ((x<<1)+1) #define MID(x,y) ((x+y)>>1) #define CLR(arr,val) memset(arr,val,sizeof(arr)) #define FAST_IO ios::sync_with_stdio(false);cin.tie(0); typedef pair<int, int> pii; typedef long long LL; const double PI = acos(-1.0); const int N = 500010; LL arr[N]; LL Max[N][20]; LL prefix[N]; void init() { CLR(Max, -0x3f3f3f3f3f3f3f3f); prefix[0] = 0LL; } void RMQ_init(int l, int r) { int i, j; for (i = l; i <= r; ++i) Max[i][0] = max<LL>(Max[i][0], prefix[i]); for (j = 1; l + (1 << j) - 1 <= r; ++j) { for (i = l; i + (1 << j) - 1 <= r; ++i) { Max[i][j] = max<LL>(Max[i][j - 1], Max[i + (1 << (j - 1))][j - 1]); } } } LL ST(int l, int r) { int k = log2(r - l + 1); return max<LL>(Max[l][k], Max[r - (1 << k) + 1][k]); } int main(void) { int tcase, n, i; LL k; scanf("%d", &tcase); while (tcase--) { init(); scanf("%d%lld", &n, &k); for (i = 1; i <= n; ++i) { scanf("%lld", &arr[i]); prefix[i] = prefix[i - 1] + arr[i]; } RMQ_init(1, n); int ans = INF; for (i = 1; i <= n; ++i) { int L = i, R = n; int temp = -1; while (L <= R) { int mid = (L + R) >> 1; LL Get = ST(i, mid); if (Get - prefix[i - 1] >= k) { temp = mid; R = mid - 1; } else L = mid + 1; } if (~temp) ans = min(ans, temp - i + 1); } printf("%d\n", ans == INF ? -1 : ans); } return 0; }
以上是关于UVALive 6609 Minimal Subarray Length(RMQ-ST+二分)的主要内容,如果未能解决你的问题,请参考以下文章
2019杭电多校第三次hdu6609 Find the answer(线段树)
hdu多校第三场 1007 (hdu6609) Find the answer 线段树