[线段树]LightOJ 1093 - Ghajini

1093 - Ghajini
Time Limit: 1 second(s)Memory Limit: 32 MB

Amir is having a short term memory problem. He can't remember anything for more than d milliseconds.

Amir is playing a game named 'Find Max Difference'. The game is actually designed for children. There is a screen which shows an integer for 1 millisecond. In the very next millisecond the screen shows another integer. The target of the game is to find the maximum difference of any two numbers shown in the screen.

But soon Amir found that the game is more difficult for him, because his short term memory problem. So, he uses a paper to write the maximum difference he has found so far. So, Amir wants your help. You have to write a program to help Amir.

Input

Input starts with an integer T (≤ 5), denoting the number of test cases.

Each case starts with two integers n (2 ≤ n ≤ 105)d (1 ≤ d ≤ n)n means the total number of integers the screen will show. The next line contains nspace separated integers in range [0, 108].

Output

For each case, print the case number and the maximum difference found by Amir.

Sample Input

Output for Sample Input

3

6 2

6 0 8 8 8 4

8 3

19 8 4 13 12 1 0 13

2 2

1 1

Case 1: 8

Case 2: 15

Case 3: 0

 

题意:给定一个序列,然后要求出所有长度为d的连续区间内最大的(最大值和最小值之差),直接建立线段树,然后枚举每个长度为d的区间保存最大值即可。

线段树功能:区间询问最大最小值,不用更新。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int MAXN = 111111;
int Max[MAXN<<2],Min[MAXN<<2],N,D,T;
void pushUP(int rt){
    Max[rt] = max(Max[rt<<1],Max[rt<<1|1]);
    Min[rt] = min(Min[rt<<1],Min[rt<<1|1]);
}
void build(int l,int r,int rt){
    if(l==r){
        scanf("%d",&Max[rt]);
        Min[rt] = Max[rt];
        return;
    }
    int m = (l+r)>>1;
    build(lson);
    build(rson);
    pushUP(rt);
}
int QueryMax(int L,int R,int l,int r,int rt){
    if(L<=l&&R>=r){
        return Max[rt];
    }
    int m = (l+r)>>1;
    int ret = -1;
    if(m>=L) ret = max(ret,QueryMax(L,R,lson));
    if(m<R)  ret = max(ret,QueryMax(L,R,rson));
    return ret;
}
int QueryMin(int L,int R,int l,int r,int rt){
    if(L<=l&&R>=r){
        return Min[rt];
    }
    int m = (l+r)>>1;
    int ret = 0x3fffffff;
    if(m>=L) ret = min(ret,QueryMin(L,R,lson));
    if(m<R)  ret = min(ret,QueryMin(L,R,rson));
    return ret;
}
int main(){
    scanf("%d",&T);
    for(int cas=1;cas<=T;cas++){
        scanf("%d%d",&N,&D);
        build(0,N-1,1);
        int ans = -1;
        for(int i=0;i<=N-D;i++){
            ans = max(ans,abs(QueryMax(i,i+D-1,0,N-1,1)-QueryMin(i,i+D-1,0,N-1,1)));
        }
        printf("Case %d: %d\n",cas,ans);
    }
    return 0;
}



 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值