圓的反演變換 cdq分治 共點圓

2021-06-22 15:17:04 字數 2720 閱讀 3742

因為所有的圓都過原點,因此可以以原點為反演中心,將所有的圓反演為一條直線,然後根據反演的性質,可以發現圓的內部會被反演到乙個半平面上去,因此每次詢問就相當於詢問點是否在半平面的交之中,這個可以動態插半平面詢問,也可以cdq分治來離線回答;詢問的時候二分點在凸包的哪塊三角形中,然後叉積一下就可以判斷了。

我採用了第二種方法,然後開始了艱苦卓絕地卡常數的歷程,歷經各種常數優化,終於把最後兩個點都卡在了3s整...

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

const double pi=acos(-1.0);

const double eps=1e-8;

const double oo=1e15,lr=100000.0;

using namespace std;

struct point

point (double x,double y)

point operator -(const point &p) const

point operator +(const point &p) const

point operator *(const double a) const

void print()

double dist()

}p[500050],b[500050];

int ans[500050],a[500050],n,st[500050],u[500050],c[500050];

inline double cr(point e,point r)

inline double dot(point &e,point &r)

inline void cross(point &p,point &q,point &e)

inline void ori(point &a)

inline bool cmp(int i,int j)

int search(point b,int tot,point &p,point &q,point &u)

return l-1;

}point ob;

bool cmp2(point i,point j)

void origin()

void point_reverse(point &p)

void circle_reverse(double x,double y,point &p)

}int main()

}origin();

calc(1,n);

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

if (c[i]) ans[i]=1;

else break;

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

if (c[i])

return 0;

}

updata:把交點存一下會快一點

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

const double pi=acos(-1.0);

const double eps=1e-8;

const double oo=1e15,lr=100000.0;

using namespace std;

struct point

point (double x,double y)

point operator -(const point &p) const

point operator +(const point &p) const

point operator *(const double a) const

void print()

double dist()

}p[500050],b[500050],st[500050];

int ans[500050],a[500050],n,st[500050],u[500050],c[500050];

inline double cr(point e,point r)

inline double dot(point &e,point &r)

inline void cross(point &p,point &q,point &e)

inline void ori(point &a)

inline bool cmp(int i,int j)

inline bool equ(point &p)

return l-1;

}point ob;

bool cmp2(point i,point j)

void origin()

void point_reverse(point &p)

void circle_reverse(double x,double y,point &p)

}int main()

}origin();

calc(1,n);

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

if (c[i]) ans[i]=1;

else break;

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

if (c[i])

return 0;

}

Mindis 圓的反演變換

題意 圓心 o 座標 0,0 給定兩點 p,q 不在圓外 滿足 po qo,要在圓上找一點 d,使得 pd qd 取到最小值。官方題解 做p點關於圓的反演點p opd與odp 相似,相似比是 op r。q點同理。極小化pd qd可以轉化為極小化p d q d。當p q 與圓有交點時,答案為兩點距離,...

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除到右邊去,...

BZOJ2961 共點圓 CDQ分治

bzoj 其實就是推一下圓的式子 長成這個樣子 假設要查詢的點是 x,y 某個圓心是 p,q x p 2 y q 2 leq p 2 q 2 變成 fracp frac leq q 那麼乙個點合法就要對所有圓心都滿足上面這個式子 很明顯拿斜率截就好啦 然後cdq維護上下凸包 附 cdq維護凸包過程 ...