1. 程式人生 > >POJ 2823 Sliding Window(單調佇列||線段樹)

POJ 2823 Sliding Window(單調佇列||線段樹)

題意:

讓你不停的查詢區間長度為k的最小值和最大值
一開始用set模擬,發現常熟太大,T了,然後開始學單調佇列,看了一會兒還是好理解的,所以就寫了,發現G++會T,只能交C++,後來發現
有人線段樹也能過,於是就寫了一發,還真行,只不過就是吧查詢的答案用全域性變數來存,減少return的時間消耗,還是隻能交C++。

單調佇列:

//
//  Created by  CQU_CST_WuErli
//  Copyright (c) 2016 CQU_CST_WuErli. All rights reserved.
//
#include <iostream>
#include <cstring>
#include <cstdio> #include <cstdlib> #include <cctype> #include <cmath> #include <string> #include <vector> #include <list> #include <map> #include <queue> #include <stack> #include <set> #include <algorithm> #include <sstream>
#define CLR(x) memset(x,0,sizeof(x)) #define OFF(x) memset(x,-1,sizeof(x)) #define MEM(x,a) memset((x),(a),sizeof(x)) #define BUG cout << "I am here" << endl #define lookln(x) cout << #x << "=" << x << endl #define SI(a) scanf("%d",&a) #define SII(a,b) scanf("%d%d",&a,&b)
#define SIII(a,b,c) scanf("%d%d%d",&a,&b,&c) #define rep(flag,start,end) for(int flag=start;flag<=end;flag++) #define Rep(flag,start,end) for(int flag=start;flag>=end;flag--) #define Lson l,mid,rt<<1 #define Rson mid+1,r,rt<<1|1 #define Root 1,n,1 const int INF_INT=0x3f3f3f3f; const long long INF_LL=0x7fffffff; const int MOD=1e9+7; typedef long long ll; using namespace std; struct Sta { int val,id; Sta(int val,int id):val(val),id(id){} }; const int N=1000010; int a[N]; int n,k; int ans[N]; void getmin() { deque<Sta> q; rep(i,1,k-1) { while (q.size() && q[q.size()-1].val>=a[i]) q.pop_back(); q.push_back(Sta(a[i],i)); } rep(i,k,n) { while (q.size() && q.back().val>=a[i]) q.pop_back(); q.push_back(Sta(a[i],i)); while (q.size() && q.front().id<=i-k) q.pop_front(); ans[i-k+1]=q.front().val; } rep(i,1,n-k+1) { printf("%d%c",ans[i],i<n-k+1?' ':'\n'); } } void getmax() { deque<Sta> q; rep(i,1,k-1) { while (q.size() && q.back().val<=a[i]) q.pop_back(); q.push_back(Sta(a[i],i)); } rep(i,k,n) { while (q.size() && q.back().val<=a[i]) q.pop_back(); q.push_back(Sta(a[i],i)); while (q.size() && q.front().id<=i-k) q.pop_front(); ans[i-k+1]=q.front().val; } rep(i,1,n-k+1) { printf("%d%c",ans[i],i<n-k+1?' ':'\n'); } } int main(int argc, char const *argv[]) { #ifdef LOCAL freopen("C:\\Users\\john\\Desktop\\in.txt","r",stdin); // freopen("C:\\Users\\john\\Desktop\\out.txt","w",stdout); #endif while(SII(n,k)==2) { rep(i,1,n) SI(a[i]); getmin(); getmax(); } return 0; }

線段樹:

//
//  Created by  CQU_CST_WuErli
//  Copyright (c) 2016 CQU_CST_WuErli. All rights reserved.
//w
#include <stdio.h>
#define CLR(x) memset(x,0,sizeof(x))
#define OFF(x) memset(x,-1,sizeof(x))
#define MEM(x,a) memset((x),(a),sizeof(x))
#define BUG cout << "I am here" << endl
#define lookln(x) cout << #x << "=" << x << endl
#define SI(a) scanf("%d",&a)
#define SII(a,b) scanf("%d%d",&a,&b)
#define SIII(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define rep(flag,start,end) for(int flag=start;flag<=end;flag++)
#define Rep(flag,start,end) for(int flag=start;flag>=end;flag--)
#define Lson l,mid,rt<<1
#define Rson mid+1,r,rt<<1|1
#define Root 1,n,1
const int INF_INT=0x3f3f3f3f;
const long long INF_LL=0x7fffffff;
const int MOD=1e9+7;
#define max(a,b) a>b?a:b
#define min(a,b) a<b?a:b
const int N=1000010*4;

int n,k;

int ans1[1000010*4];
int ans2[1000010*4];

void pushup(int rt) {
    ans1[rt]=max(ans1[rt<<1],ans1[rt<<1|1]);
    ans2[rt]=min(ans2[rt<<1],ans2[rt<<1|1]);
}

void build(int l,int r,int rt) {
    int mid;
    if (l==r) {
        scanf("%d",ans1+rt);
        ans2[rt]=ans1[rt];
        return ;
    }
    mid=(l+r)>>1;
    build(Lson);
    build(Rson);
    pushup(rt);
}

int maxx;
void queryMax(int L,int R,int l,int r,int rt) {
    int mid;
    if (L<=l && r<=R) {
        maxx=max(maxx,ans1[rt]);
        return;
    }
    mid=(l+r)>>1;
    if (L<=mid) queryMax(L,R,Lson);
    if (R>mid) queryMax(L,R,Rson);
    return;
}

int minx;
void queryMin(int L,int R,int l,int r,int rt) {
    int mid;
    if (L<=l && r<=R) {
        minx=min(minx,ans2[rt]);
        return;
    }
    mid=(l+r)>>1;
    if (L<=mid) queryMin(L,R,Lson);
    if (R>mid) queryMin(L,R,Rson);
    return;
}

int main(int argc, char const *argv[]) {
#ifdef LOCAL
    freopen("C:\\Users\\john\\Desktop\\in.txt","r",stdin);
    // freopen("C:\\Users\\john\\Desktop\\out.txt","w",stdout);
#endif
    int i;
    while(SII(n,k)==2) {
        build(1,n,1);

        for(i=1;i<=n-k+1;i++) {
            minx=INF_INT;
            queryMin(i,i+k-1,1,n,1);
            printf("%d",minx);
            if (i<n-k+1) printf(" ");
            else printf("\n");
        }
        for(i=1;i<=n-k+1;i++) {
            maxx=-INF_INT;
            queryMax(i,i+k-1,1,n,1);
            printf("%d",maxx);
            if (i<n-k+1) printf(" ");
            else printf("\n");
        }
    }
    return 0;
}

相關推薦

POJ 2823 Sliding Window單調佇列||線段

題意: 讓你不停的查詢區間長度為k的最小值和最大值 一開始用set模擬,發現常熟太大,T了,然後開始學單調佇列,看了一會兒還是好理解的,所以就寫了,發現G++會T,只能交C++,後來發現 有人線段樹也能過,於是就寫了一發,還真行,只不過就是吧

POJ 2823 Sliding Window單調佇列 || 線段題解

題意:求每個長度為k的陣列的最大值和最小值思路:1.用線段樹建立維護最大值和最小值,遍歷詢問,簡單複習了一下...有點手生2.單調佇列:可以看一下詳解單調佇列顧名思義就是一個單調遞增或者遞減的佇列,我們可以通過佇列瞬間得到當前佇列的最大值和最小值。以查詢當前區間最小值為例,我

POJ 2823 Sliding Window單調佇列入門題

Sliding Window Time Limit: 12000MS Memory Limit: 65536K Total Submissions: 67218 Accepted: 19088 Case Time Limit: 5000MS Description An array of size 

POJ-2823-Sliding Window 單調佇列

原題連結: http://poj.org/problem?id=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 ver

POJ 2823 Sliding Window 單調佇列@

An array of size n ≤ 10 6 is given to you. There is a sliding window of size kwhich is moving from the very left of the array to the ve

poj 2823 Sliding Window單調佇列模板

介紹單調佇列不錯的部落格:點選開啟連結 還有這題輸出用printf G++交會T,C++就能過.....而用cout兩個都能過..好坑.... 程式碼: #include<cstdio> using namespace std; const int maxn

POJ - 2823 Sliding Window單調佇列優化dp && c++快讀】

Sliding Window Time Limit: 12000MS   Memory Limit: 65536K Total Submissions: 72718 &nb

Poj 2823 Sliding Window單調佇列學習】模板記錄

Sliding Window Time Limit: 12000MS Memory Limit: 65536K Total Submissions: 62889 Accepted: 17951 Case Time Limit: 5000MS Descripti

POJ 2823 Sliding Window經典單調佇列

An array of size n ≤ 10 6 is given to you. There is a sliding window of size kwhich is moving from the very left of the array to the ve

POJ 2823Sliding Window單調佇列

Sliding Window Time Limit: 12000MS Memory Limit: 65536K Total Submissions: 56138 Accepted: 1613

2823 Sliding Window單調佇列優化dp && c++快讀】

Sliding Window Time Limit: 12000MS Memory Limit: 65536K Total Submissions: 72718 Acc

[poj2823]sliding windows單調佇列模板題

DescriptionAn array of size n ≤ 106 is given to you. There is a sliding window of size k which is moving from the very left of the array t

單調佇列 POJ 2823 Sliding Window

  Sliding Window An array of size n ≤ 10 6 is given to you. There is a sliding window of size kwhich is moving from

POJ 2823 Sliding Window (單調佇列)

題目連結 Description An array of size n ≤ 106 is given to you. There is a sliding window of size k which is moving from the v

POJ 2823 Sliding Window(單調佇列)

題意  長度為n的陣列上有個長度為k的滑窗從左向右移動  求每次移動後滑窗區間的最小值和最大值  輸出兩行  第一行所有最小值  第二行所有最大值 可以用線段樹來做  但是單調佇列更簡單  單調遞增佇列: 隊尾單調入隊(入隊元素大於隊尾元素時直接入隊  否則隊尾出隊直到隊尾

洛谷P1886 滑動窗口POJ.2823 Sliding Window區間最值

最大 ide dma include names target org void blog To 洛谷.1886 滑動窗口 To POJ.2823 Sliding Window 題目描述 現在有一堆數字共N個數字(N<=10^6),以及一個大小為k的窗口。現在這個

POJ 2823 Sliding Window? (模板題)【單調隊列】

返回 一個 color www. 新元素 arc 維護 記錄 一段 <題目鏈接> <轉載於>>> > 題目大意: 給你一段序列和一個長為k的窗口,這個窗口從最左邊逐漸向右滑,直到滑到最右邊,問你,該窗口在滑動的過程中,最大值和最小值

[POJ2823] [POJ0604月賽] Sliding Window [單調佇列/線段]

大家都知道的單調佇列模板題 被卡時間了,難受 poj上G++過不去 只能換C++ #include<cstdio> #include<iostream> #include<algorithm> #include<cs

POJ2823 Sliding Window單調佇列】【線段】【ST表】

Sliding Window 題意: 給出一個長度為N的序列,通過一個視窗,可以看到序列中連續的K個元素,視窗從最左邊出發,每次移動一個單位,對於每次移動,輸出當前視窗中的最大值和最小值 單調遞減佇列:從隊頭到隊尾單調遞減的佇列 入隊操作,先把隊尾元素中小於X的元

POJ 2823 Sliding Window【RMQ壓縮長度確定

題意:給一個長度為N的陣列,輸出所有區間長度為K的陣列元素的最大值與最小值; AC程式碼: #include<cstdio> #include<algorithm> u