luogu P1440 求m區間內的最小值
阿新 • • 發佈:2017-05-17
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區間內的最小值