HDU 5289 Assignment (monotonous Queue), hdu5289
Question: give T-foot data, and then each group has n and k, which indicates n numbers, k indicates the maximum allowed capability difference, and the next n indicates the capabilities of n people, there are several intervals in which the difference of performance is within k.
Analysis: Maintain the maximum and minimum values of an interval so that their difference is smaller than k, so monotonous queues are used.
Common monotonous queue practices:
# Include <cstdio> # include <cstring> # include <algorithm> # include <cmath> using namespace std; const int maxn = 1e6 + 5; int a [maxn]; struct node {int index; int v;} qd [maxn]; node qx [maxn]; int main () {int t; scanf ("% d", & t ); while (t --) {int n, k; scanf ("% d", & n, & k); for (int I = 1; I <= n; I ++) {scanf ("% d", & a [I]);} int st1, st2, ed1, ed2; st1 = st2 = ed1 = ed2 = 1; long sum = 0; int j = 1; for (int I = 1; I <= n & j <= n; I ++) {if (I = 1) {qd [1]. index = qx [1]. index = 1; qd [1]. v = qx [1]. v = a [1];} else {while (st1 <= ed1) {// maintain the maximum value of the monotonic queue if (qd [ed1]. v <= a [I]) ed1 --; // an output queue else break that is smaller than a [I] and smaller than I;} qd [++ ed1]. v = a [I]; // a [I] Incoming queue qd [ed1]. index = I; while (st2 <= ed2) {// maintain the minimum value of the monotonic queue if (qx [ed2]. v> = a [I]) ed2 --; // an output queue else break that is larger than a [I] and smaller than I;} qx [++ ed2]. v = a [I]; // a [I] Inbound queue qx [ed2]. index = I; while (qd [st1]. v-qx [st2]. v> = k & st1 <= ed1 & st2 <= ed2) // count {if (qd [st1]. index = j) st1 ++; if (qx [st2]. index = j) st2 ++; sum + = (I-j); j ++ ;}} while (j <= n) {sum + = (n-j + 1); j ++;} printf ("% I64d \ n", sum );}}
Binary monotonous queue practices:
# Include <cstdio> # include <cstring> # include <algorithm> # include <cmath> using namespace std; const int maxn = 1e6 + 5; int a [maxn]; struct node {int index; int v;} qd [maxn]; node qx [maxn]; int maxc (int l, int r, int d) {// second point: locate the value of d in the queue until the while (l <= r) {int mid = (l + r)/2; if (qd [mid]. v = d) return mid; else if (qd [mid]. v> d) l = mid + 1; else r = mid-1;} return l;} int minc (int l, int r, int d) {// second point: locate the value of d in the queue until the while (l <= r) {int mid = (l + r)/2; if (qx [mid]. v = d) return mid; else if (qx [mid]. v <d) l = mid + 1; else r = mid-1;} return l;} int main () {int t; scanf ("% d ", & t); while (t --) {int n, k; scanf ("% d", & n, & k); for (int I = 1; I <= n; I ++) {scanf ("% d", & a [I]);} int st1, st2, ed1, ed2; st1 = st2 = ed1 = ed2 = 1; long sum = 0; int j = 1; for (int I = 1; I <= n & j <= n; I ++) {if (I = 1) {qd [1]. index = 1; qd [1]. v = a [1]; qx [1]. index = 1; qx [1]. v = a [1];} else {ed1 = maxc (st1, ed1, a [I]); // until the d enters the queue, maintain the maximum qd [ed1]. v = a [I]; qd [ed1]. index = I; ed2 = minc (st2, ed2, a [I]); // finds the end of d's entry into the queue in two minutes, and maintains the minimum value qx [ed2]. v = a [I]; qx [ed2]. index = I; while (qd [st1]. v-qx [st2]. v> = k & st1 <= ed1 & st2 <= ed2) // count {if (qd [st1]. index = j) st1 ++; if (qx [st2]. index = j) st2 ++; sum + = (I-j); j ++ ;}} while (j <= n) {sum + = (n-j + 1); j ++;} printf ("% I64d \ n", sum );}}
Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.