1. 程式人生 > >nefu 1268 區間最小值求和(單調佇列)

nefu 1268 區間最小值求和(單調佇列)

區間最小值求和

Problem:1268

Time Limit:2000ms

Memory Limit:65535K

Description

有一個包含n個正整數的數列a[1]~a[n],求數列中所有長度為k的區間的最小值的和?

Input

輸入包含多組資料。每組資料第一行為n和k(1<=n<=1e6,1<=k<=n),第二行為n個正整數a[i](0<=a[i]<=1e9)。

Output

輸出所有長度為k的區間的最小值的和。

Sample Input

9 5
3 21 5 6 23 5 2 5 7
10 4
1 2 3 5 5 3 6 3 21 3

Sample Output

14
18

中文題。

思路:單調佇列

當時用RMQ寫超記憶體了。後來學習了單調佇列的寫法,就能過。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=1e6+5;
int q[maxn],a[maxn];
int main()
{
    int n,k;
    while(~scanf("%d%d",&n,&k))
    {
        int head=1,tail=1;
        long long sum=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            while(head<tail&&a[q[tail-1]]>a[i]) tail--;
            q[tail++]=i;
            if(q[head]<i-k+1) head++;
            if(i>=k) sum+=a[q[head]];
        }
        printf("%lld\n",sum);
    }
    return 0;
}