Given a sequence a (0) with a length of N, a (1),..., A (n-1) and an integer k. Find the sequence B (i) =min{a (i), A (i+1),..., A (i+k-1)} (i=0,1,2,3,..., n-k);
Restrictive conditions: 1<=k<=n<=10^6 0<=ai<=10^9
Train of thought: similar to a window with a length of k on the whole number of the slide, to find the window containing the minimum amount of numbers;
You can use RMQ to solve in O (nlogn) complexity, this is the introduction of the two-terminal queue;
A two-terminal queue (that is, a monotone queue) that inserts and deletes an element's data structure at the head and tail,
constructs a monotonically ascending queue, an initial two-terminal queue is empty, and, when I join I, the value J at the end of the queue satisfies a[j]>=a[i], and the Until the queue is empty or a[j]<a[i] then add I at the end. The two-end queue header is the minimum value.
Time complexity: Because of the addition and deletion of the two-terminal queue, O (n) times, so the complexity of the whole algorithm is O (n);
Code:
Enter
int n,k;
int A[MAXN];
int B[MAXN];
int deq[maxn];//Double-end queue
void Solve () {
int s=0,t=0;//two-terminal queue header and tail for
(int i=0;i<n;i++)//Add I {at the end of the two-terminal queue
while (S<t&&a[deq[t]]>=a[i]) t--;//joins I, determines whether the value at the end of the two-end queue satisfies >=a[i]
deq[++t]=i;
if (i-k+1>=0) {
b[i-k+1]=a[deq[s]];//equals two-end queue header
if (deq[s]==i-k+1)//remove element from head of two-terminal queue
s++;
}
for (int i=0;i<=n-k;i++)
printf ("%d%c", b[i],i==n-k?) \ n ': ');