poj 2823 线段树

An array of size n ≤ 10 6 is given to you. There is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves rightwards by one position. Following is an example:
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

The input consists of two lines. The first line contains two integers n and k which are the lengths of the array and the sliding window. There are n integers in the second line.

Output

There are two lines in the output. The first line gives the minimum values in the window at each position, from left to right, respectively. The second line gives the maximum values.

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


 

线段树水题,但这道题拿线段树是卡过的,拿G++提交就会超时,所以必须用C++提交。

 

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
const int MAXN = 1000005;
int datain[MAXN];//下标从1开始,边的编号。
int Min[MAXN*2],Max[MAXN*2];//线段树的结点编号从0开始。
int lnext[MAXN*2],rnext[MAXN*2];
int l[MAXN*2],r[MAXN*2];
int tot;
int buildTree(int ll,int rr)
{
    int cur=tot++;
    l[cur]=ll;
    r[cur]=rr;
    if(ll==rr)
    {
        Min[cur] = Max[cur] = datain[ll];
        //printf("%d**\n",seg[cur]);
        lnext[cur]=rnext[cur]=-1;
        return cur;
    }
    int mid=(ll+rr)>>1;
    lnext[cur]=buildTree(ll,mid);
    rnext[cur]=buildTree(mid+1,rr);
    Min[cur]=min(Min[lnext[cur]],Min[rnext[cur]]);
    Max[cur]=max(Max[lnext[cur]],Max[rnext[cur]]);
    return cur;
}
int qmin(int ll,int rr,int cur)
{
    //printf("%d %d %d\n",cur,l[cur],r[cur]);
    if(l[cur]==ll&&r[cur]==rr) return Min[cur];
    int mid=(l[cur]+r[cur])/2;
    if(ll>=mid+1) return qmin(ll,rr,rnext[cur]);
    else if(rr<mid+1) return qmin(ll,rr,lnext[cur]);
    else return min(qmin(ll,mid,lnext[cur]),qmin(mid+1,rr,rnext[cur]));
}
int qmax(int ll,int rr,int cur)
{
    //printf("%d %d %d\n",cur,l[cur],r[cur]);
    if(l[cur]==ll&&r[cur]==rr) return Max[cur];
    int mid=(l[cur]+r[cur])/2;
    if(ll>=mid+1) return qmax(ll,rr,rnext[cur]);
    else if(rr<mid+1) return qmax(ll,rr,lnext[cur]);
    else return max(qmax(ll,mid,lnext[cur]),qmax(mid+1,rr,rnext[cur]));
}

int main()
{
    int n,k;
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        if(k>n) k=n;
        for(int i=1; i<=n; i++)
        {
            scanf("%d",&datain[i]);
        }
        int Min,Max;
        buildTree(1,n);
        for(int i=1; i<=n-k+1; i++) printf("%d ",qmin(i,i+k-1,0));
        puts("");
        for(int i=1; i<=n-k+1; i++) printf("%d ",qmax(i,i+k-1,0));
        puts("");

    }
}
时间: 2024-08-01 18:02:33

poj 2823 线段树的相关文章

POJ 2528 (线段树+离散化) Mayor&#39;s posters

因为将每个单位都作为一个最小单元的话会爆内存的 所以,将海报的每个端点进行排序,将这些端点最为最小的区间. 毕竟是刚刚接触线段树,理解起来还有些吃力,还是那句话,题做多了慢慢就好了. 萌萌的AC代码君贴上. 1 //#define LOCAL 2 #include <iostream> 3 #include <algorithm> 4 #include <cmath> 5 using namespace std; 6 7 int n; 8 struct CPost 9

poj 2777 线段树的区间更新

Count Color Time Limit: 1000 MS Memory Limit: 65536 KB 64-bit integer IO format: %I64d , %I64u Java class name: Main [Submit] [Status] [Discuss] Description Chosen Problem Solving and Program design as an optional course, you are required to solve al

转载::POJ 2991 线段树+计算几何(有c++结构体操作)

POJ 2991 线段树+计算几何 (2011-02-27 21:13:44) 转载▼ 标签: 杂谈 分类: OI 话说这一题真的是很恶心很恶心,不过确实改变了我对线段树的一些看法,算是很经典的题目. 题意:有一个吊车由很多个不同长度的线段组成,一开始是一条长直线起点在(0,0),尾节点在(0,sum[n]),每条线段之间的夹角的初始值是180度.然后有一些操作a. b将第a条线段和a+1之间的夹角变成b度,经过每一次操作都要求出尾节点的坐标. 首先要用到一个计算几何的知识(没学过..请教而来)

poj 2750(线段树的动态规划)

Potted Flower Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4186   Accepted: 1581 Description The little cat takes over the management of a new park. There is a large circular statue in the center of the park, surrounded by N pots of f

POJ 2570 线段树

Potted Flower Time Limit: 2000 MS Memory Limit: 65536 KB 64-bit integer IO format: %I64d , %I64u Java class name: Main [Submit] [Status] [Discuss] Description The little cat takes over the management of a new park. There is a large circular statue in

poj 2828 线段树

http://poj.org/problem?id=2828 学到的思维: 1.变化的或者后来的优先影响前面的,那么从最后一个往前看,最后一个就成了 确定的, 并且后来的也可以确定----如果从前往后,所有的随时都不是确定的 2.线段树叶子节点直接维护区间(线段)信息,非叶子节点v维护的是以v为树根的整个子树的信息,那么假设父节点rt信息为[l,r]那么左子树维护[l,mid],右子树维护[mid+1,r]的信息.如果如果是前缀和,rt里是1-n的和,左子树1~n/2的和,右子树是n/2+1~n

POJ 3468 线段树+lazy标记

lazy标记 Time Limit:5000MS     Memory Limit:131072KB     64bit IO Format:%I64d & %I64u Submit Status Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to

POJ 3667 线段树的区间合并简单问题

题目大意:有一排标号1-N的房间.操作一:询问是不是有连续长度为a的空房间,有的话住进最左边(占用a个房间)操作二:将[a,a+b-1]的房间清空(腾出b个房间)思路:记录每个区间中“靠左”“靠右”“中间”的空房间线段树操作:update:区间替换query:询问满足条件的最左端点 题目链接: http://vjudge.net/problem/viewProblem.action?id=10354 题目操作: 因为这里找从最左边住起的房间,所以这里不能像常规地写query函数那样写了,终于发现

poj 2886 线段树的更新+反素数

Who Gets the Most Candies? Time Limit: 5000 MS Memory Limit: 0 KB 64-bit integer IO format: %I64d , %I64u Java class name: Main [Submit] [Status] [Discuss] Description N children are sitting in a circle to play a game. The children are numbered from