Time Limit: 12000MS | Memory Limit: 65536K | |
Total Submissions: 58321 | Accepted: 16711 | |
Case Time Limit: 5000MS |
Description
The array is [1 3 -1 -3 5 3 6 7], and k is 3.
Window position | Minimum value | Maximum value |
---|---|---|
[1 3 -1] -3 5 3 6 7 | -1 | 3 |
1 [3 -1 -3] 5 3 6 7 | -3 | 3 |
1 3 [-1 -3 5] 3 6 7 | -3 | 5 |
1 3 -1 [-3 5 3] 6 7 | -3 | 5 |
1 3 -1 -3 [5 3 6] 7 | 3 | 6 |
1 3 -1 -3 5 [3 6 7] | 3 | 7 |
Your task is to determine the maximum and minimum values in the sliding window at each position.
Input
Output
Sample Input
8 3 1 3 -1 -3 5 3 6 7
Sample Output
-1 -3 -3 -3 3 3 3 3 5 5 6 7
Source
POJ Monthly--2006.04.28, Ikki
传送门:poj 2823
思路:这一题我刚开始认为有专门的奇淫巧技,我还想了好久,但是看了网上的题解之后,我发现一般就是两种做法,一种是:优先队列(这个另外发一个blog),还有一个就是直接用线段树维护,最大值跟最小值,就是非常容易超时,我优化了好久,但是后来看到网上有大神说用不需要优化的线段树就可以ac,难道是当初我学线段树的模板优化的不够好吗?向大佬低头....剪枝优化果然很重要啊!
Node tree[MAXN]存放线段树,Node包含两个int类型的成员变量:mins-最小值,maxs-最大值,初始化时,将叶子节点的最大值跟最小值都赋值为相同的值,并不断更新区间的最大值与最小值,由于要求的输出比较奇怪,是最大值占一行,最小值占一行,所以另外设置两个数组存放区间段的最大值跟最小值,详细见代码:
/*
*Li Wenjun
*Email:1542113545@qq.com
*/
#include<stdio.h>
#include<string.h>
#include<math.h>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#include <vector>
#include <cctype>
#include <stack>
#include <list>
#include <cstdlib>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define mid (l+r)>>1
#define lson l,m,rt<<1
#define rson m+1,r,(rt<<1)|1
const int MAXN = 1000005;
struct Node{
int maxs;
int mins;
}tree[MAXN << 2];
int n,k;
int mins[MAXN],maxs[MAXN];
int push_up(int rt)
{
tree[rt].mins = min(tree[rt<<1].mins,tree[(rt<<1)|1].mins);
tree[rt].maxs = max(tree[rt<<1].maxs,tree[(rt<<1)|1].maxs);
return 0;
}
int build(int l,int r,int rt)
{
if(l==r)
{
scanf("%d",&tree[rt].mins);
tree[rt].maxs = tree[rt].mins;
return 0;
}
int m = mid;
build(lson);
build(rson);
push_up(rt);
return 0;
}
void query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
mins[L] = min(mins[L],tree[rt].mins);
maxs[L] = max(maxs[L],tree[rt].maxs);
return ;
}
int m = mid;
if(L<=m) query(L,R,lson);
if(m<R) query(L,R,rson);
return ;
}
int main()
{
//freopen("in.txt", "r", stdin);
while(scanf("%d%d",&n,&k)!=EOF)
{
memset(mins,INF,sizeof(mins));
memset(maxs,-INF,sizeof(maxs));
build(1,n,1);
for(int i=1;i<=n-k+1;i++)
{
query(i,i+k-1,1,n,1) ;
}
for(int i=1;i<=n-k+1;i++)
{
printf("%d ",mins[i]);
}
printf("\n");
for(int i=1;i<=n-k+1;i++)
{
printf("%d ",maxs[i]);
}
printf("\n");
}
return 0;
}