天使玩偶(CDQ分治 最小曼哈頓距離)

2021-09-26 19:45:05 字數 1712 閱讀 2799

題意:有兩種操作:

給二維平面上加入乙個點

詢問二維平面上到某個點最近的乙個點(用曼哈頓距離來表示)

思路:標準的cdq分治,離線處理兩種操作

當想到cdq分治後本題的重點在於如何處理曼哈頓距離,畢竟看到絕對值都頭疼

我們最希望的是能去掉絕對值!這裡有一種處理方法:我們只考慮每個詢問點左下角的點,則顯然可以去掉絕對值,用普通的cdq分治,按照x

xx座標排序,按照y

yy座標將x+y

x+yx+

y插入樹狀陣列,並求出每個詢問點左下角最大的x+y

x+yx+

y的值,就可以求出這種情況的解

對於另外三種情況,分別將x

xx,y

yy進行倒置(細節見**),也就是一共跑四遍cdq分治即可

當然還有一些優化,比如每次cdq以前,先將完全不可能在任何詢問左下角的點給刪掉;還有max

,min

max,min

max,mi

n的加速。

#include "bits/stdc++.h"

#define hhh printf("hhh\n")

#define see(x) (cerr<<(#x)<<'='<<(x)inline int read()

const int maxn = 6e5+10;

const int mod = 2e9+7;

const double eps = 1e-9;

const int maxx = 2e6+10;

struct p

p(int f, int x, int y, int id): f(f), x(x), y(y), id(id) {}

bool operator < (const p &rhs) const

inline void clear(int x)

inline void update(int x, int d)

inline int query(int x)

void pre()

void solve(int l, int r)

int tmp=query(a[i].y);

if(tmp) min(ans[a[i].id],a[i].x+a[i].y-tmp);

}while(--j>=l) if(!a[j].f) clear(a[j].y);

}int main()

while(m--)

++mx, ++my, mm=mx+my;

for(int i=1; i<=n; ++i) a[i]=a1[i], ans[i]=1e9;

pre(); solve(1,nx);

for(int i=1; i<=n; ++i) a[i]=a1[i], a[i].x=mx-a[i].x;

pre(); solve(1,nx);

for(int i=1; i<=n; ++i) a[i]=a1[i], a[i].y=my-a[i].y;

pre(); solve(1,nx);

for(int i=1; i<=n; ++i) a[i]=a1[i], a[i].x=mx-a[i].x, a[i].y=my-a[i].y;

pre(); solve(1,nx);

for(int i=1; i<=n; ++i) if(a1[i].f) printf("%d\n", ans[i]);

}

VIOLET 3 天使玩偶 CDQ分治好題

題目描述 ayu 在七年前曾經收到過乙個天使玩偶,當時她把它當作時間囊埋在了地下。而七年後 的今天,ayu 卻忘了她把天使玩偶埋在了 所以她決定僅憑一點模糊的記憶來尋找它。我們把 ayu 生活的小鎮看作乙個二維平面座標系,而 ayu 會不定時地記起可能在某個點 xmy 埋下了天使玩偶 或者 ayu ...

哈夫曼樹 計算最小WPL

哈夫曼樹,第一行輸入乙個數n,表示葉結點的個數。需要用這些葉結點生成哈夫曼樹,根據哈夫曼樹的概念,這些結點有權值,即weight,題目需要輸出所有結點的值與權值的乘積之和。輸入有多組資料。每組第一行輸入乙個數n,接著輸入n個葉節點 葉節點權值不超過100,2 n 1000 輸出權值。示例1 複製5 ...

使用最小堆構造哈夫曼樹

哈夫曼樹 構造哈夫曼樹的演算法 構造哈夫曼樹的思路 程式實現 typedef struct huffmantree htree typedef struct heap minheap typedef htree elementtype struct huffmantree struct heap m...