線段樹專題 等差子串行 BZOJ 2124

2021-08-28 16:50:46 字數 2994 閱讀 7303

感謝孫耀峰的線段樹ppt,使我獲益匪淺.

b zo

j−

2124

bzoj-2124

bzoj−2

124給出長度為n

nn的1−n

1-n1−

n的排列a

aa問是否存在一組1≤p

1≤p2

≤...

≤pl≤

n,l≥

31 \le p_1 \le p_2 \le ... \le p_l \le n,l \ge 3

1≤p1​≤

p2​≤

...≤

pl​≤

n,l≥

3使得ap1

,ap2

,...

,apl

a_,a_,...,a_

ap1​,a

p2​,

...,

apl​

構成等差序列

資料範圍n≤1

04

n \le 10^4

n≤10

4只要能形成長度為3

33的等差子串行,就直接輸出yes

yesye

s即可.

即需要尋找i,j

,k

i,j,k

i,j,

k滿足ai=

aj−t

,ak=

aj+t

,且

t>

0.a_i = a_j - t,a_k = a_j + t,且t > 0.

ai​=aj

​−t,

ak​=

aj​+

t,且t

>0.

根據轉化後的式子,我們只需要列舉j

jj,判斷是否存在這樣的t

tt即可.

考慮到a

aa是乙個排列,排列中的數兩兩不同,因此我們可以考慮開乙個資料結構維護一下內容:

當列舉到a

ja_j

aj​的時候,我可以很快的查詢任何乙個a

ia_i

ai​在a

ja_j

aj​的左邊還是右邊,(記如果i

ija_j

aj​應該標記為0

00表示在左邊,若i

>

ji>j

i>j則a

ja_j

aj​應該標記為1

11表示在右邊).

這樣的話,如果01

0101

串[ aj

−t,a

j−1]

[a_j-t,a_j-1]

[aj​−t

,aj​

−1]與[aj

+1,a

j+t]

[a_j+1,a_j+t]

[aj​+1

,aj​

+t]之間有一位不相同(也就是說存在關於a

ja_j

aj​的對稱位置的兩個數在a

ja_j

aj​兩側,說明可以形成等差子串行).

因此只有當以上兩個01串,翻轉過來完全相同的情況下,才不存在以a

ja_j

aj​作為中心的等差序列.

如何判斷01

0101

串相同呢?答案是雜湊.

建立一顆線段樹,維護的是01

0101

串的正向和反向雜湊值.

從小到大列舉aj,

[1,n

]a_j,[1,n]

aj​,[1

,n],然後更新線段樹,並判斷是否有以a

ja_j

aj​為對稱中心的等差序列.

#include

#include

const

int n =

10007

;typedef

unsigned

long

long ull;

int t,n;

int a[n];

ull pow[n]

;struct work

;#define pr(x) std::cout << #x << ": " << x << std::endl

struct segtree

void

change

(int rt,

int l,

int r,

int pos,

int val)

int mid =

(l + r)/2

;if(pos > mid)

change

(rt*2+

1,mid+

1,r,pos,val)

;else

change

(rt*

2,l,mid,pos,val)

;maintain

(rt,l,r);}

work query

(int rt,

int l,

int r,

int ql,

int qr);}

else

if(ql <= l && r <= qr);}

int mid =

(l + r)/2

; work wa =

query

(rt*

2,l,mid,ql,qr)

; work wb =

query

(rt*2+

1,mid+

1,r,ql,qr)

;return

(work);}

}seg;

intmain()

}if(!f)

std::cout <<

"n"<< std::endl;

else

std::cout <<

"y"<< std::endl;

}return0;

}

BZOJ 2124 等差子串行 線段樹 hash

題目傳送門 等等 這題好像在 做過 哦,codeforces 452f,原題哈 為什麼我還是不會做啊 就當是複習一遍吧,這種想法還是挺好的。p.s.wa了兩發,錯在了updata上 好像updata這個地方好容易出錯啊。附上ac include include include using names...

BZOJ2124 等差子串行 線段樹 hash

傳送門 給出乙個n的排列,問是否存在乙個長度至少為3的等差子串行 n 10000 注意到我們給出的是乙個排列,而且我們只需要找長度為3的子串行即可 那麼我們可以列舉中間項x,用01串s和t來表示x前面的數中 1,x 1 和 x 1,x x 1 是否出現,每次判斷串s和t的反串是否相等即可,如果不相等...

BZOJ 2124等差子串行 線段樹 hash

題目描述 description 給乙個 1 到 n 的排列,詢問是否存在 1 p1 3 使得 ap1,ap2,ap3,aplen 是乙個等差序列。輸入描述 input description 輸入的第一行包含乙個整數 t,表示組數。下接 t 組資料,每組第一行乙個整數 n,每組第二行為乙個 1 到...