poj2823/hdu3415 - 数据结构 单调队列

poj2823 题目链接

长度为N的数组,求宽度k的滑动窗口在数组上滑动时窗口内的最大值或最小值

 

如果用单调队列做,求最小值时,队列应该严格递增的。所以插入时,队尾大于等于插入值的元素都应被舍弃,因为插入元素不仅小而且新,没有必要保留队尾这些又大又旧的元素。

/*
选C++交是5k多毫秒,但是G++就会超时。
*/
#include <cstdio> #include <cstring> const int N = 1000100; int data[N]; int o1[N],o2[N]; int q[N]; int n,k; void getMin(){ int head,tail; head = tail = 0; for(int i=0;i<n;i++){ while((tail>head)&&data[q[tail-1]]>data[i]) tail--; q[tail++] = i; if(i>=(k-1)){ while((head<tail)&&q[head]<(i-k+1)) head++; o1[i-k+1] = data[q[head]]; } } } void getMax(){ int head,tail; head = tail = 0; for(int i=0;i<n;i++){ while((head<tail)&&(data[q[tail-1]]<data[i])) tail--; q[tail++] = i; if(i>=(k-1)){ while((head<tail)&&(q[head]<(i-k+1))) head++; o2[i-k+1] = data[q[head]]; } } } int main(){ scanf("%d%d",&n,&k); for(int i=0;i<n;i++) scanf("%d",data+i); getMin(); getMax(); for(int i=0;i<n-k+1;i++) printf("%d ",o1[i]); puts(""); for(int i=0;i<n-k+1;i++) printf("%d ",o2[i]); puts(""); return 0; }

 hdu3415 题目链接

长度为N的数组,长度小于等于K的非空子串的最大和。

 

求完前缀和后就转化成了窗宽为k的单调队列

#include <cstdio>
#include <cstring>
const int N = 100100;
const int INF = 0x0FFFFFFF;
int data[N],sum[N*2];
int q[N*2];
int n,k,total;
int minq(int &spos,int &epos){
    int head,tail;
    head = tail = 0;
    int ans = -INF;
    for(int i=1;i<total;i++){
        while((head<tail)&&(sum[q[tail-1]]>=sum[i-1])) tail--;
        while((head<tail)&&q[head]<i-k) head++;
        q[tail++] = i-1;
        if((sum[i]-sum[q[head]]>ans)){
            spos = q[head];
            epos = i;
            ans = sum[epos]-sum[spos];
        }
    }
    return ans;
}
int main(){
    int t;
    for(scanf("%d",&t);t--;){
        scanf("%d%d",&n,&k);
        sum[0] = 0;
        for(int i=1;i<=n;i++){
            scanf("%d",data+i);
            sum[i]=sum[i-1]+data[i];
        }
        for(int i=1;i<k;i++) sum[n+i]=sum[n+i-1]+data[i];
        
        total = n+k;
        int spos,epos;
        int ans = minq(spos,epos);
        spos++;
        if(epos>n) epos-=n;
        if(spos>n) spos-=n;
        printf("%d %d %d\n",ans,spos,epos);
    }
    return 0;
} 

 

posted @ 2017-04-26 19:17  redips  阅读(166)  评论(0编辑  收藏  举报