http://www.lightoj.com/volume_showproblem.php?problem=1093
题意:给定序列,问长度为d的区间最大值和最小值得差最大是多少。
思路:可以使用线段树做,由于固定区间长度,还可以使用单调队列。
/** @Date : 2016-12-06-18.39
* @Author : Lweleth (SoungEarlf@gmail.com)
* @Link : https://github.com/
* @Version :
*/
#include<bits/stdc++.h>
#define LL long long
#define PII pair
#define MP(x, y) make_pair((x),(y))
#define fi first
#define se second
#define PB(x) push_back((x))
#define MMG(x) memset((x), -1,sizeof(x))
#define MMF(x) memset((x),0,sizeof(x))
#define MMI(x) memset((x), INF, sizeof(x))
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 1e5+20;
const double eps = 1e-8;
struct yuu
{
int l, r;
int ma;
int mi;
}tt[N << 2];
int a[N];
void pushup(int p)
{
tt[p].ma = max(tt[p << 1].ma, tt[p << 1 | 1].ma);
tt[p].mi = min(tt[p << 1].mi, tt[p << 1 | 1].mi);
}
void build(int l, int r, int p)
{
tt[p].l = l;
tt[p].r = r;
tt[p].ma = 0;
tt[p].mi = INF;
if(l == r)
{
tt[p].ma = tt[p].mi = a[l];
return ;
}
int mid = (l + r) >> 1;
build(l , mid, p << 1);
build(mid + 1, r, p << 1 | 1);
pushup(p);
}
void updata(int l, int r, int v, int p)
{
if(l <= tt[p].l && r >= tt[p].r)
{
return ;
}
int mid = (tt[p].l + tt[p].r) >> 1;
if(l <= mid)
updata(l, r, v, p << 1);
if(r > mid)
updata(l, r, v, p << 1 | 1);
pushup(p);
}
PII query(int l, int r, int p)//直接返回pair会超时
{
//cout <<tt[p].ma <<"~" <<tt[p].mi << endl;
if(l <= tt[p].l && r >= tt[p].r)
return MP(tt[p].ma, tt[p].mi);
int mid = (tt[p].l + tt[p]. r) >> 1;
PII ans;
ans.fi = 0;
ans.se = INF;
if(l <= mid)
{
ans.fi = max(ans.fi, query(l, r, p << 1).fi);
ans.se = min(ans.se, query(l, r, p << 1).se);
}
if(r > mid)
{
ans.fi = max(ans.fi, query(l, r, p << 1 | 1).fi);
ans.se = min(ans.se, query(l, r, p << 1 | 1).se);
}
return ans;
}
int queryma(int l, int r, int p)
{
if(l <= tt[p].l && r >= tt[p].r)
return tt[p].ma;
int mid = (tt[p].l + tt[p].r) >> 1;
int ma = 0;
if(l <= mid)
ma = max(ma, queryma(l, r, p << 1));
if(r > mid)
ma = max(ma, queryma(l, r, p << 1 | 1));
return ma;
}
int querymi(int l, int r, int p)
{
if(l <= tt[p].l && r >= tt[p].r)
return tt[p].mi;
int mid = (tt[p].l + tt[p].r) >> 1;
int mi = INF;
if(l <= mid)
mi = min(mi, querymi(l, r, p << 1));
if(r > mid)
mi = min(mi, querymi(l, r, p << 1 | 1));
return mi;
}
int main()
{
int T;
int cnt = 0;
cin >> T;
while(T--)
{
int n, d;
scanf("%d%d", &n, &d);
for(int i = 1; i <= n; i++)
{
scanf("%d", a + i);
}
build(1, n, 1);
//cout << query(2, 3, 1) << endl;
int ma = 0;
for(int i = 1; i + d - 1 <= n; i++)
{
//PII x = query(i, i + d - 1, 1);
ma = max(queryma(i, i + d - 1, 1) - querymi(i, i + d - 1, 1), ma);
//cout << ma <<endl;
}
printf("Case %d: %d\n", ++cnt, ma);
}
return 0;
}