POJ2823 Sliding Window

  首先吐槽题目,害的我交了三次错程序上去,题目里面说的清清楚楚,数是integer,integer,呵呵,我一开始最大最小值定义为32768,-32768,最后交了前三次的结果都是Wrong Answer,后来我觉得实在没有什么地方可以改了,就把最大最小值改成long下的值,直接AC,程序效率相当之低,几乎是踩着线过数据的。

  题目意思很清楚,背景故事什么的没细看,总之意思就是给你N个数,以及一个K,现在让你求[0,K-1],[1,K],...,[N-k,N-1]这些区间中的最大最小值。

  对于区间问题,我首选的还是线段树,正好上次acm校赛线段树的失利历历在目,所以再写一次线段树很有必要。

  代码:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#define MAXN 1000000
#define MAX 2147483647
#define MIN -2147483647
struct linet {
    int l , r;
    int max , min;
};
int N , K , NN = 0;
int a[MAXN];
linet tree[MAXN*3];

inline int miner(int x , int y) {
    if (x < y) return x;
    return y;
}

inline int maxer(int x , int y) {
    if (x > y) return x;
    return y;
}

void    create(int l , int r , int n) {
    NN = maxer(NN,n);
    tree[n].l = l; tree[n].r = r;
    if (l == r) {
        tree[n].max = tree[n].min = a[l];
    }
    else {
        int mid = (l+r) >> 1;
        create(l,mid,n*2+1);
        create(mid+1,r,n*2+2);
        tree[n].max = maxer(tree[n*2+1].max,tree[n*2+2].max);
        tree[n].min = miner(tree[n*2+1].min,tree[n*2+2].min);
    }
}

int getmin(int l , int r , int n) {
    if (l <= tree[n].l && tree[n].r <= r) return tree[n].min;
    if (tree[n].r < l || tree[n].l > r) return MAX;
    int p1 = MAX, p2 = MAX;
    if (n*2+1 <= NN) p1 = getmin(l,r,n*2+1);
    if (n*2+2 <= NN) p2 = getmin(l,r,n*2+2);
    return miner(p1,p2);
}

int getmax(int l , int r , int n) {
    if (l <= tree[n].l && tree[n].r <= r) return tree[n].max;
    if (tree[n].r < l || tree[n].l > r) return MIN;
    int p1 = MIN, p2 = MIN;
    if (n*2+1 <= NN) p1 = getmax(l,r,n*2+1);
    if (n*2+2 <= NN) p2 = getmax(l,r,n*2+2);
    return maxer(p1,p2);
}

int main () {
    scanf("%d%d",&N,&K);
    for (int i = 0;i < N;i++)
      scanf("%d",&a[i]);
    create(0,N-1,0);
    printf("%d",getmin(0,K-1,0));
    for (int i = 1;i <= N-K;i++)
      printf(" %d",getmin(i,i+K-1,0));
    printf("\n%d",getmax(0,K-1,0));
    for (int i = 1;i <= N-K;i++)
      printf(" %d",getmax(i,i+K-1,0));
    printf("\n");
    return 0;
}

  尽管早有心理准备,知道线段树效率应该很低,还特地换成类C语句来写,想稍微提高点速度,但是效果依然不行。

  测试结果:

你可能感兴趣的:(window)