Bzoj4237 cdq分治 樹狀陣列 單調棧

2022-05-02 02:18:07 字數 1810 閱讀 9193

二維平面在某區域內點的問題,要麼樹套樹,kdtree,要麼就是cdq分治了。

然而這題樹套樹和kdtree都不是很好搞的樣子,於是我們就只能cdq分治了。

首先把點按照橫座標x排序,在每一層我們需要算出右邊的點和左邊的點組成的點對的貢獻。

我們先把這些點按照縱座標降序排列。

考慮我們按照縱座標從大到小掃瞄到的每乙個點。

如果他是右邊的點,需要橫座標比他上面的點大才能直接加入,否則他會擋住其右上方的點,使其無法成為答案。

於是單調棧維護一下就好了。

對於左邊的點,他能構成答案的縱座標區間,一定要在他本身縱座標以上且其右上方的點的最低縱座標以下才行。

所以這個,我們可以用樹狀陣列以橫座標x為下標維護縱座標y的字尾min(什麼你說樹狀陣列只能維護字首?字尾座標轉化為n-x[i]+1不就成字首了?)。

然後就是查詢,由於我懶得考慮二分的細節了,所以又用另外乙個樹狀陣列維護右面的點在縱座標y上的區間和。

詳見下面的圖。

注意這題保證橫縱座標沒有重複,所以對拍寫maker的時候注意不要出重複座標,否則網上的**誰跟誰跑的都不一樣,別問我怎麼知道的。

然後給一組資料:

53 1

1 32 5

4 25 4

答案是4。

最後上**:

1 #include2 #include3 #include4

#define lli long long int

5using

namespace

std;

6const

int maxn=2e5+1e2;

7const

int inf=0x3f3f3f3f;8

9struct

node

14}ns[maxn];

1516

intx[maxn],y[maxn];

17int

id[maxn],stk[maxn],top;

18int

n;19

lli ans;

2021

struct

binaryindextreea

25 inline void update(int pos,int

x) 28 inline int query(int

pos)

33 inline void reset(int

pos)

36}bx;

37struct

binaryindextreeb

43 inline lli query(int

pos)

48 inline void reset(int

pos)

51}by;

5253 inline bool cmp(int a,int

b) 56 inline void solve(int l,int

r) else74}

75for(int i=r;i>=l;i--)

80solve(l,mid);

81 solve(mid+1

,r);82}

8384 inline void refac(int*sou)

91 inline void ncpy(int

ope) else

if( !~ope ) 99}

100101

intmain()

view code

BZOJ4237 稻草人 CDQ分治

joi村有一片荒地,上面豎著n個稻草人,村民們每年多次在稻草人們的周圍舉行祭典。有一次,joi村的村長聽到了稻草人們的啟示,計畫在荒地中開墾一片田地。和啟示中的一樣,田地需要滿足以下條件 田地的形狀是邊平行於座標軸的長方形 左下角和右上角各有乙個稻草人 田地的內部 不包括邊界 沒有稻草人。給出每個稻...

bzoj 4237 稻草人 CDQ分治

time limit 40 sec memory limit 256 mb joi村有一片荒地,上面豎著n個稻草人,村民們每年多次在稻草人們的周圍舉行祭典。有一次,joi村的村長聽到了稻草人們的啟示,計畫在荒地中開墾一片田地。和啟示中的一樣,田地需要滿足以下條件 田地的形狀是邊平行於座標軸的長方形 ...

bzoj 3262(cdq分治 樹狀陣列)

正經題解在後面 斜體字都是一年前在沒有把cdq扯清楚的情況下應付的,即使現在真正理解了cdq,還是將這堆話留在這,畢竟,花無重開日,人無再少年 runid user problem result memory time language code length submit time 2374693...