BZOJ2961 共點圓 CDQ分治

2022-05-07 10:00:10 字數 1477 閱讀 1595

bzoj

其實就是推一下圓的式子

長成這個樣子

假設要查詢的點是(x, y) 某個圓心是(p, q)

\((x - p)^2 + (y - q)^2 \leq p^2 + q^2\)

變成\(-\fracp + \frac \leq q\)

那麼乙個點合法就要對所有圓心都滿足上面這個式子

很明顯拿斜率截就好啦

然後cdq維護上下凸包

附:cdq維護凸包過程

void cdq(int l, int r)

for(int i = mid + 1, j1 = 1, j2 = t2; i <= r; ++i)

cdq(mid + 1, r);

歸併,按照x排序

}

如果你wa了你要知道

這道題不可以用叉積判凸包

這道題不可以做完減法判slope

這道題不可以不加eps

我哭遼qvq

#include #include #include #include #include #define sqr(x) ((x)*(x))

using namespace std;

const int n = 5e5 + 5;

const double eps = 1e-11;//這裡1e-8到1e-11都可以

struct node

}node[n], stk[n], s1[n], s2[n];

int n;

double slope(node a,node b)

for(int i = mid + 1, j1 = 1, j2 = t2; i <= r; ++i)

else

} //printf("%d %d\n", l, r);

cdq(mid + 1, r);

tl = l, tr = mid + 1, t1 = l;

while(tl <= mid && tr <= r)

if(node[tl] < node[tr]) stk[t1++] = node[tl++];

else stk[t1++] = node[tr++];

while(tl <= mid) stk[t1++] = node[tl++];

while(tr <= r) stk[t1++] = node[tr++];

for(int i = l; i <= r; ++i) node[i] = stk[i];

}int main()

sort(node + 1, node + n + 1, rule_k);

cdq(1, n);

sort(node + 1, node + n + 1, rule_t);

for(int i = 1; i <= n; ++i)

} system("pause");

return 0;

}

bzoj 2961 共點圓 cdq分治

這道題目資料很弱不保證我的程式完全正確qaq。另外這道題目在2013年集訓隊 中有提到。以下是窩的口胡 對於乙個點 x0,y0 和乙個圓心為 x,y 的圓,顯然當 x0 x 2 y0 y 2 x 2 y 2時點在圓內,化簡得到 2y y0 2x x0 x0 2 y0 2,然後可以把2y0除到右邊去,...

BZOJ 2961 共點圓 CDQ分治 凸包

題目大意 給定平面,多次插入點和圓,每次插入點時詢問當前插入的點是否在之前插入的所有圓中並且至少在乙個圓中 直接用資料結構維護這些點和圓不是很好寫,我們考慮cdq分治 對於每層分治,我們需要對於 mid 1,r 中的每個點求出 l,mid 中是否所有的圓都覆蓋了這個點 設點的座標為 x0,y0 那麼...

BZOJ2961 共點圓 cdq分治 凸包

bzoj傳送門 首先考慮乙個點 x 0,y 0 什麼時候在乙個圓 x 1,y 1,sqrt 內 顯然有 x 12 y 12 geq x 0 x 1 2 y 0 y 1 2 化簡 2x 0x 1 2y 0y 1 geq x 02 y 02 所有含 x 1,y 1 的項挪到同一邊,除掉乙個 2y 0 假...