現在有一堆數字共n個數字(n<=10^6),以及乙個大小為k的視窗。現在這個從左邊開始向右滑動,每次滑動乙個單位,求出每次滑動後視窗中的最大值和最小值。
例如:the array is [1 3 -1 -3 5 3 6 7], and k = 3.
輸入格式:
輸入一共有兩行,第一行為n,k。
第二行為n個數(輸出格式:
輸出共兩行,第一行為每次視窗滑動的最小值
第二行為每次視窗滑動的最大值
50%的資料,n<=10^5
100%的資料,n<=10^6
一般人切這道題都用的st表或者是單調佇列
我手殘打了個線段樹(其實是因為我太菜了不會上面兩個)
我線段樹維護兩個值,乙個是區間最大值,乙個是區間最小值
每次修改,在修改完葉子結點(單點插入,我當做修改處理)後,我向上pushup更新區間最值
每個節點表示的是他所負責的線段的區間最值
查詢常規查詢即可
//luogu-judger-enable-o2
#include#include
#include
#include
#define rii register int i
#define rij register int j
#define rs 1048576
#define inf 1<<30
using
namespace
std;
struct
nodx[
7000005
];int
n,k;
void add(long
long wz,long
long l,long
long r,long
long val,long
long
bh)
long
long ltt=(l+r)/2
;
if(wz>ltt)
else
x[bh].mi=min(x[bh*2].mi,x[bh*2+1
].mi);
x[bh].ma=max(x[bh*2].ma,x[bh*2+1
].ma);
}struct
csans;
cs query(
long
long l,long
long r,long
long nl,long
long nr,long
long
bh)
if(r>nr)
cs an,bn;
an.maxn=-inf;
an.minx=inf;
bn.maxn=-inf;
bn.minx=inf;
if(l==nl&&r==nr)
int ltt=(nl+nr)/2
;
if(l<=ltt)
if(r>ltt)
an.maxn=max(an.maxn,bn.maxn);
an.minx=min(an.minx,bn.minx);
return
an;}
long
long minn[1000005
];int
main()
scanf(
"%d%d
",&n,&k);
for(rii=1;i<=n;i++)
for(rii=1;i<=n-k+1;i++)
printf("\n
");for(rii=1;i<=n-k+1;i++)
}
線段樹維護區間01
g.小 w 開關燈 problem 4467 discussion description 晚上到家小 w 通過開關燈來保持自己神經的興奮以便清醒地理筆記。n n 2 n 100,000 2 n 100,000 盞燈被連續的編號為 1 n 1 n 剛回到家的時候,所有的燈都是關閉的。小w 通過 n ...
維護序列(線段樹維護區間乘 區間加)
給定乙個長度為n的原序列和模數mod,m個操作,a,b 區間乘c,a,b 區間加c,統計 a,b 的區間和。思路 線段樹維護的還是區間和,但是這裡我們需要用到兩個懶標記,乙個記錄加法,乙個記錄乘法,乘法懶標記下傳之後要重置為1而不是0。對於乙個乘法操作,他影響的是區間和還有這個區間的加法標記 乘法標...
(線段樹)過滑動視窗
上一次我們談論單調佇列,這樣是可以過滑動視窗的 void slove min 利用單調佇列的單調性,如果頭不是最小就將頭更新,最大反之即可 但對於區間查詢這類的問題線段樹一般都能過,這道題只需要線段樹裡面的建樹,查詢點即可,呢麼學了線段樹單調佇列就沒用了麼,也不是的對於動態規劃裡面的優化,單調佇列也...