Question: For an integer sequence (which may have negative numbers), find the shortest continuous sequence so that the sum of the sequences is greater than or equal to integer x;
Solution: the first is the complexity of On:
Sum [j]-sum [I]> = x. If there are two decision j <j 'and sum [j]> = sum [j'], then j is useless. That is, a sum [j] incremental sequence is maintained. Then we can perform a binary search every time, but here we have a feature that we want to obtain the nearest one. We can maintain a left pointer at the same time. The left pointer is used to follow up the left boundary of the more rows of answers, because the maintained monotonous stack will not be moved to the left side of left (because the answer that can be updated on the right side of left will certainly not be smaller ).
The second method is RMQ, which is easier to understand: Enumerate I, and then calculate sum [j]-sum [I]> = j, which is the smallest of x. Total complexity nlogn
The first code:
/*************************************** * **************** Author: xiefubao *************************************** * ***************/# pragma comment (linker, "/STACK: 102400000,102400000") # include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
// Freopen ("in.txt", "r", stdin); using namespace std; # define eps 1e-8const double pi = acos (-1.0); typedef long LL; const int Max = 500100; const int INF = 1000000007; int n, x; LL num [Max]; LL que [Max]; LL sum [Max]; int increase [Max]; int main () {int t; cin> t; while (t --) {scanf ("% d", & n, & x); for (int I = 1; I <= n; I ++) {scanf ("% lld", num + I ); sum [I] = sum [I-1] + num [I];} int right = 1; increase [0] = 1; int left = 0; int ans = n + 1; for (int I = 2; I <= n; I ++) {while (right> left & sum [increase [right-1]> = sum [I]) right --; increase [right ++] = I; while (right> left + 1 & sum [I]-sum [increase [left]> = x) {ans = min (ans, I-increase [left]); left ++ ;}} if (ans = n + 1) cout <"-1 \ n "; else cout
<第二份代码:
/*************************************** * **************** Author: xiefubao *************************************** * ***************/# pragma comment (linker, "/STACK: 102400000,102400000") # include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
// Freopen ("in.txt", "r", stdin); using namespace std; # define eps 1e-8const double pi = acos (-1.0); typedef long LL; const int Max = 500100; const int INF = 1000000007; int n, x; LL dp [Max] [30]; int mm [Max]; // initialize RMQ, the subscript of array B starts from 1 and starts from 0. void RMQ (int n, LL B []) {mm [0] =-1; for (int I = 1; I <= n; I ++) {mm [I] = (I & (I-1) = 0 )? Mm [I-1] + 1: mm [I-1]; dp [I] [0] = B [I];} for (int j = 1; j <= mm [n]; j ++) for (int I = 1; I + (1 <
> T; while (t --) {scanf ("% d", & n, & x); for (int I = 1; I <= n; I ++) scanf ("% lld", num + I), sum [I] = sum [I-1] + num [I]; RMQ (n, sum ); int ans = n + 3; for (int I = 0; I
= X) r = mid; else l = mid + 1;} if (sum [r]-sum [I]> = x) ans = min (ans, r-I); if (sum [l]-sum [I]> = x) ans = min (ans, l-I );} if (ans = n + 3) ans =-1; cout <