乙個含有n項的數列(n<=2000000),求出每一項前的m個數到它這個區間內的最小值。若前面的數不足m項則從第1個數開始,若前面沒有數則輸出0。
輸入格式:
第一行兩個數n,m。
第二行,n個正整數,為所給定的數列。
輸出格式:
n行,第i行的乙個數ai,為所求序列中第i個數前m個數的最小值。
輸入樣例#1:
6 27 8 1 4 3 2
輸出樣例#1:
077113
【資料規模】
m≤n≤2000000
很顯而易見的板子題。想練練rmq-st
但是maxn = 2000000,用沒有滾動陣列rmq-st會mle兩個點。。。
1 #include 2 #include 3using
namespace
std;
4const
int n = 2000010;5
6int
a[n];78
int mn[n][25];9
10int
n, m, q, l, r;
1112
struct
rmq
20int query(int ql, int
qr)
24}rmq;
2526
void
work()
30 r = i - 1;31
if (i - m <= 0) l = 1;32
else l = i -m;
33 printf("
%d\n
", rmq.query(l, r));34}
35}3637
intmain()
然而懶得寫不會滾動陣列
所以用了簡潔明瞭的單調佇列
1 #include2 #include3 #include4 #include5 #include67using
namespace
std;89
const
int maxn = 2000010;10
inthead,tail;
11int
n,k,a[maxn];
1213
struct
node change;
16node que[maxn];
1718 inline int
read()
21while (ch >= '
0' && ch <= '
9')
22return num *f;23}
2425
intmain()
40return0;
41 }
下面發一波滾動陣列版的看碼風就知道不是我寫的
1 #include 23using
namespace
std;45
const
int maxn = 2000005;6
inta[maxn],bp,n;
7int f[maxn][2
]; 8
intg[maxn];910
intmain()
1121
int t = 0
;22 printf("
0\n"
);23 now = 2;24
for (int j = 0; (1
<< j) <= bp; ++j)
2531
else
3237}38
while (now <= n && min(now - 1, bp) < (1
<< (j + 1
)))
3948}49
return0;
50 }
比較神奇的是,zkw線段樹也不會t掉看碼風就知道這也不是我寫的
#include#includeusing
namespace
std;
int n,m,tree[4000001
];int
main()
printf(
"%d\n
",ans);
}return0;
}
the end
luogu P1440 求m區間內的最小值
乙個含有n項的數列 n 2000000 求出每一項前的m個數到它這個區間內的最小值。若前面的數不足m項則從第1個數開始,若前面沒有數則輸出0。輸入格式 第一行兩個數n,m。第二行,n個正整數,為所給定的數列。輸出格式 n行,第i行的乙個數ai,為所求序列中第i個數前m個數的最小值。輸入樣例 1 6 ...
Luogu P1440 求m區間內的最小值
這題可以用rmq st表 做!由於本題資料的特殊性,需要查詢的區間的元素個數大部分是一樣的 除了輸出的前 m 行元素個數不足 m 個的情況 我們就可以把st表 中 a 陣列 進行降維攻擊 霧 這樣一來使用rmq st表 就不會mle了!在時間方面,我們可以拿個變數 中 power 儲存 2 的 j ...
P1440 求M區間內的最小值
乙個含有 nn 項的數列,求出每一項前的 mm 個數到它這個區間內的最小值。若前面的數不足 mm 項則從第 11 個數開始,若前面沒有數則輸出 00。第一行兩個整數,分別表示 nn,mm。第二行,nn 個正整數,為所給定的數列 a ia i nn 行,每行乙個整數,第 ii 個數為序列中 a ia ...