題意:有兩種操作:
給二維平面上加入乙個點
詢問二維平面上到某個點最近的乙個點(用曼哈頓距離來表示)
思路:標準的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...