1. 程式人生 > >luogu P1440 求m區間內的最小值

luogu P1440 求m區間內的最小值

using 個數 print 規模 put 序列 == fin 區間

題目描述

一個含有n項的數列(n<=2000000),求出每一項前的m個數到它這個區間內的最小值。若前面的數不足m項則從第1個數開始,若前面沒有數則輸出0。

輸入輸出格式

輸入格式:

第一行兩個數n,m。

第二行,n個正整數,為所給定的數列。

輸出格式:

n行,第i行的一個數ai,為所求序列中第i個數前m個數的最小值。

輸入輸出樣例

輸入樣例#1:
6 2
7 8 1 4 3 2
輸出樣例#1:
0
7
7
1
1
3 

說明

【數據規模】

m≤n≤2000000

線段樹

維護最小值

#include<cstdio>
#include
<iostream> #include<algorithm> using namespace std; #define N 8000006 int a[N],sum[N]; int read() { int sum = 0, fg = 1; char c = getchar(); while(c < 0 || c > 9) { if (c == -) fg = -1; c = getchar(); } while(c >= 0 && c <= 9) { sum = sum * 10 + c -
0; c = getchar(); } return sum * fg; } void update(int rt) { sum[rt]=min(sum[rt<<1],sum[rt<<1|1]); } void build(int l,int r,int rt) { if(l==r) { sum[rt]=a[l]; return; } int m=(l+r)>>1; build(l,m,rt<<1); build(m
+1,r,rt<<1|1); update(rt); } int ans; int nowr,nowl; void query(int l,int r,int rt){ if(nowr>=r&&nowl<=l) { ans=min(ans,sum[rt]);return ; } int m=(r+l)>>1; if(nowl<=m)query(l,m,rt<<1); if(nowr>m)query(m+1,r,rt<<1|1); } int ans1; int main() { int n,m; n=read(); m=read(); for(int i=1;i<=n;i++) a[i]=read(); build(1,n,1); for(int i=1;i<=n;i++) { if(i==1) { puts("0"); continue; } else { nowr=i-1; if(i-m>=1) nowl=i-m; else nowl=1; } ans=0x7fffffff; query(1,n,1); printf("%d\n",ans);//線段樹 } return 0; }

luogu P1440 求m區間內的最小值