PKU 2823 Sliding Window(线段树||RMQ||单调队列)

#include<cstdio>
#include<algorithm>
#define maxn 1000005
#define inf 0x3f3f3f3f
using namespace std;
int Segtree_min[maxn<<2],Segtree_max[maxn<<2];
int n,k,value;
int begin,end;
//每个结点保存该区间线段的最大/小值
void Build(int l,int r,int pos)
{
    if(l==r){
        scanf("%d",&value);
        Segtree_max[pos]=Segtree_min[pos]=value;
        return ;
    }
    int mid=(l+r)/2;
    Build(l,mid,2*pos);
    Build(mid+1,r,2*pos+1);
    Segtree_min[pos]=min(Segtree_min[2*pos],Segtree_min[2*pos+1]);
    Segtree_max[pos]=max(Segtree_max[2*pos],Segtree_max[2*pos+1]);
}
int Query_min(int ll,int rr,int l,int r,int pos)
{
    if(ll<=l&&r<=rr)
        return Segtree_min[pos];
    int mid=(l+r)/2;
    //int begin=inf,end=inf;
    if(ll<=mid)
        begin=Query_min(ll,rr,l,mid,2*pos);
    if(rr>mid)
        end=Query_min(ll,rr,mid+1,r,2*pos+1);
    return min(begin,end);
}
int Query_max(int ll,int rr,int l,int r,int pos)
{
    if(ll<=l&&r<=rr)
        return Segtree_max[pos];
    int mid=(l+r)/2;
    //int begin=-inf,end=-inf;
    if(ll<=mid)
        begin=Query_max(ll,rr,l,mid,2*pos);
    if(rr>mid)
        end=Query_max(ll,rr,mid+1,r,2*pos+1);
    return max(begin,end);
}

int main()
{
    scanf("%d%d",&n,&k);
    Build(1,n,1);
    for(int i=1;i<=n-k+1;i++)
        printf("%d ",Query_min(i,i+k-1,1,n,1));
    printf("\n");
    for(int i=1;i<=n-k+1;i++)
        printf("%d ",Query_max(i,i+k-1,1,n,1));
    printf("\n");
}
时间: 2024-12-22 04:43:56

PKU 2823 Sliding Window(线段树||RMQ||单调队列)的相关文章

POJ 2823 Sliding Window 线段树区间求和问题

题目链接 线段树区间求和问题,维护一个最大值一个最小值即可,线段树要用C++交才能过. 注意这道题不是求三个数的最大值最小值,是求k个的. 还有一种做法是单调队列,耗时更少. #include <iostream> #include <cstdio> #include <cmath> #include <cstring> #include <algorithm> #define N 1000005 using namespace std; int

POJ 2823 Sliding Window (线段树区间查询)

题目大意: 解题思路: 代码: 1 # include<iostream> 2 # include<cstdio> 3 4 using namespace std; 5 6 # define inf 99999999 7 # define MAX 1000010 8 9 struct Segtree 10 { 11 int left, right; 12 int mx, mn; 13 }tree[MAX*4]; 14 15 int a[MAX]; 16 int maxx,minx;

CDOJ Sliding Window 线段树(nlogn)或双端队列(n) 模板

题目链接: L - Sliding Window Time Limit:6000MS     Memory Limit:131072KB     64bit IO Format:%lld & %llu Submit Status Practice UESTC 201 Appoint description:  System Crawler  (2016-04-24) Description An array of size n≤106 is given to you. There is a sl

BZOJ 1012 线段树或单调队列

1012: [JSOI2008]最大数maxnumber 题意:两种操作:1.查询当前数列中末尾L个数中的最大的数:2.当前数列末尾插入一个数. tags:水题 线段树 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define FF(i,a,b) for (int i=a;i<=b;i++) #define F(i

ZOJ 3632 Watermelon Full of Water(dp+线段树或单调队列优化)

Watermelon Full of Water Time Limit: 3 Seconds      Memory Limit: 65536 KB Watermelon is very popular in the hot summer. Students in ZJU-ICPC Team also love watermelon very much and they hope that they can have watermelon to eat every day during the

Luogu4085 [USACO17DEC]Haybale Feast (线段树,单调队列)

\(10^18\)是要long long的. \(nlogn\)单调队列上维护\(logn\)线段树. #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #define R(a,b,c) for(register int a = (b); a <= (c); ++ a) #define nR(a,b,c

bzoj 1171 并查集优化顺序枚举 | 线段树套单调队列

详见vfleaking在discuss里的题解. 收获: 当我们要顺序枚举一个序列,并且跳过某些元素,那么我们可以用并查集将要跳过的元素合并到一起,这样当一长串元素需要跳过时,可以O(1)跳过. 暴力: 1 /************************************************************** 2 Problem: 1171 3 User: idy002 4 Language: C++ 5 Result: Accepted 6 Time:1908 ms 7

poj 2823 Sliding Window 单调队列或线段树

题目链接:http://poj.org/problem?id=2823 Sliding Window Time Limit: 12000MS   Memory Limit: 65536K Total Submissions: 38315   Accepted: 11350 Case Time Limit: 5000MS Description An array of size n ≤ 106 is given to you. There is a sliding window of size k

POJ 2823 Sliding Window 单调队列题解

本题是单调队列题解的入门,当然也可以使用RMQ 和 线段树,不过速度都没有单调队列那么快. 单调队列难点: 1 如何入列,保存数据 -- 最小单调队列的时候, 所有数都入列一次,在新的数据准备入列的时候,增加判断,如果当前数值小于队尾数值,那么队尾数值就出列.空队列的时候直接入列. 2 保存的数列是什么样的? 举例吧: 1 3 -1 -3 5 3 6 7 构建最小单调队列 第一个数值1的时候,空队列,那么入列,得到: 1 第二个数值3, 因为大于1:那么1不用出列,直接入列,得到: 1 3 第三