VIOLET 3 天使玩偶 CDQ分治好題

2021-08-29 04:10:51 字數 3052 閱讀 8807

題目描述

ayu 在七年前曾經收到過乙個天使玩偶,當時她把它當作時間囊埋在了地下。而七年後 的今天,ayu 卻忘了她把天使玩偶埋在了**,所以她決定僅憑一點模糊的記憶來尋找它。

我們把 ayu 生活的小鎮看作乙個二維平面座標系,而 ayu 會不定時地記起可能在某個點 (xmy) 埋下了天使玩偶;或者 ayu 會詢問你,假如她在 (x,y) ,那麼她離近的天使玩偶可能埋下的地方有多遠。

因為 ayu 只會沿著平行座標軸的方向來行動,所以在這個問題裡我們定義兩個點之間的距離為dist(a,b)=|ax-bx|+|ay-by|。其中 ax 表示點 a的橫座標,其餘類似。

輸入格式:

第一行包含兩個整數n和m ,在剛開始時,ayu 已經知道有n個點可能埋著天使玩偶, 接下來 ayu 要進行m 次操作

接下來n行,每行兩個非負整數 (xi,yi),表示初始n個點的座標。

再接下來m 行,每行三個非負整數 t,xi,yi。

如果t=1 ,則表示 ayu 又回憶起了乙個可能埋著玩偶的點 (xi,yi) 。

如果t=2 ,則表示 ayu 詢問如果她在點 (xi,yi) ,那麼在已經回憶出來的點裡,離她近的那個點有多遠

輸出格式:

對於每個t=2 的詢問,在單獨的一行內輸出該詢問的結果。

輸入樣例#1:

2 31 1

2 32 1 2

1 3 3

2 4 2

輸出樣例#1:12

這道題真的鍛鍊本蒟蒻的心態。

題解

借這篇題解也總結一下對於cdq分治的理解。

如果能看出這題可以cdq分治,那可以好想得多。

對於帶修改(初值也可以看做是修改)和查詢的問題,考慮怎樣的修改會對怎樣的查詢產生什麼樣的貢獻,如果發現這能轉換為偏序問題來考慮的話那麼多半可以用cdq分治了。

其實一般的偏序問題用cdq來處理的操作並不是很難,關鍵是對問題的轉換,或者說是對查詢的轉化或分解

就拿這題來說。

這題看到二維平面以及查詢和加點,那麼大致就知道要怎麼用cdq做了。(如果神的話就秒切了) 我們按照上面的思維來,考慮哪些修改會對哪些查詢會有影響。對於乙個查詢無非是時序早與這個查詢的所有修改都對其有影響。

嗯,這樣的話,情況就很複雜了。

先不急,我們接著按上面的思路走,乙個怎樣的修改對對乙個怎樣的查詢有什麼樣的貢獻貢獻。我們考慮題目中的這個式子dist(a,b)=|ax-bx|+|ay-by|嗯,絕對值太討厭了,我們將它拆開。那麼接下來就是大力分類討論了。我們以乙個查詢點為原點建立平面直角座標系,那麼對於四個象限有不同的偏序條件和貢獻計算方法(這裡可以理解成將乙個查詢分成向四個方向的查詢)。嗯,那就可以寫了,四個cdq走起額,四個cdq碼量和細節都太多了,我們考慮乙個更簡單~~(細節**)~~ 的做法——翻轉座標系:將所有象限都翻轉成第三象限來處理,翻轉很簡單,用座標值的值域減去原座標就是翻轉後的座標了(建議在紙上畫一畫)

想到這裡就差不多做完了,但是我們發現如果將n+m個點拿去跑cdq似乎效率過不去,我們考慮優化。優化的方法很簡單,就是將n個已知的點拿出來,不拿去做cdq,而是排序好,然後再單獨計算這n個點對所有查詢的貢獻。

這樣做應該就好了,不過細節真的不多。

#include

#include

#include

#include

#define n 500005

#define v 1000002

#define ll long long

using namespace std;

inline

intread()

int n,m,ans[n]

,tr[v+5]

;struct nodea[n]

,b[n]

,c[n]

,d[n]

,e[n]

;inline

void

flip

(node &p,

int k)

p.s=p.x+p.y;

}inline bool cmp

(node u,node v)

inline

void

clean

(int x)

inline

void

update

(int x,

int v)

inline

intquery

(int x)

inline

void

cdq(

int l,

int r)

else

while

(j<=r)

for(

int k=l;k(d[k]

.t<2)

clean

(d[k]

.y);

while

(i<=mid) e[ind++

]=d[i++];

for(

int k=l;k<=r;k++

) d[k]

=e[k];}

intmain()

for(

;j<=m;j++)if

(d[j]

.t>

1) ans[d[j]

.id]

=min

(d[j]

.s-query

(d[j]

.y),ans[d[j]

.id]);

}for

(int i=

1;i<=m;i++)if

(b[i]

.t>1)

printf

("%d\n"

,ans[i]);

return0;

}

bzoj2716 Violet 3 天使玩偶

傳送門 這題好像有cdq分治做法 不過我太菜了沒聽懂 於是我打了一發kdtree 度娘 k d樹 k dimensional樹的簡稱 是一種分割k維資料空間的資料結構。主要應用於多維空間關鍵資料的搜尋 如 範圍搜尋和最近鄰搜尋 k d樹是二進位制空間分割樹的特殊的情況。大概思路就是每次確定乙個軸,將...

BZOJ2716 Violet 3 天使玩偶

bzoj2716 violet 3 天使玩偶 試題描述 輸入 輸出 輸入示例 第乙個測試點,我就不拿來佔頁面了 輸出示例 同上資料規模及約定 題目中給的範圍不對。交上去re。我目測大概 n,m 600000,xi,yi 107.題解 出題人cnbb!1.資料超大,時限 80 sec,出題人惡意卡測評...

BZOJ2716 Violet 3 天使玩偶

題解 通過取絕對值考慮後 發現是乙個較複雜的cdq 突然考慮距離問題 用kdtree寫也是可行的 但是.會退化 所以我們考慮用替罪羊樹來防止退化 include include include include include include include include include inclu...