基本(2D)计算几何

点/向量的定义

struct Vec{
db x,y; Vec(){} Vec(db _x, db _y){x=_x,y=_y;}
inline Vec operator + (Vec b){return Vec(x+b.x,y+b.y);}
inline Vec operator - (Vec b){return Vec(x-b.x,y-b.y);}
inline Vec operator - (){return Vec(-x,-y);}
inline db operator * (Vec b){return x*b.x+y*b.y;}
inline db operator % (Vec b){return x*b.y-b.x*y;}
inline db operator ~ (){return x*x+y*y;}
inline bool operator ==(Vec b){return fabs(x-b.x) <= EPS && fabs(y-b.y) <= EPS;}
inline bool operator !=(Vec b){return fabs(x-b.x) >  EPS || fabs(y-b.y) >  EPS;}
inline Vec Unit(){static db _; return _ = sqrt(x*x+y*y), Vec( x/_,y/_);}
inline Vec Norm(){static db _; return _ = sqrt(x*x+y*y), Vec(-y/_,x/_);}
inline bool Quad(){return y > EPS || (fabs(y) <= EPS && x >= -EPS);}
inline bool operator < (Vec b){return fabs(y-b.y) <= EPS ? x < b.x : y < b.y;}
};  typedef Vec Pt;
inline Vec operator / (Vec a, db k){return Vec(a.x/k,a.y/k);}
inline Vec operator * (db k, Vec a){return Vec(k*a.x,k*a.y);}
inline Vec operator * (Vec a, db k){return Vec(k*a.x,k*a.y);}
inline bool Para(Vec a, Vec b){return fabs(a%b) <= EPS;}
inline bool ToLeft(Vec a, Vec b){return b%a > EPS;}
inline void O(Pt a, char c = ' '){printf("(%.3f,%.3f)%c",a.x,a.y,c);}

\begin{aligned} \vert a \times b \vert &= \vert a \vert \vert b \vert \vert \sin (a,b) \vert \\ a \cdot b &= \vert a \vert \vert b \vert \cos \langle a,b \rangle \\ \end{aligned}

向量旋转

\begin{bmatrix} \cos \theta & - \sin \theta \\ \sin \theta & \cos \theta \\ \end{bmatrix} \begin{bmatrix} x \\ y \\ \end{bmatrix} = \begin{bmatrix} x' \\ y' \\ \end{bmatrix}

直线/线段的定义

struct Line{
Pt p[2]; Line(){} Line(Pt a, Pt b){p[0]=a,p[1]=b;}
inline Pt& operator[](int i){return p[i];}
inline Vec v(){return p[1]-p[0];}
};
inline bool operator < (Line a, Line b){
return Para(a.v(),b.v()) && a.v()*b.v() > EPS ? ToLeft(a[0]-b[0],b.v()) : cmpang(a.v(),b.v());
}

假 · 直线相交

inline Pt Cross(Line a, Line b){
static db _1, _2;
_1 = (b[0]-a[0])%(b[1]-a[0]), _2 = (b[1]-a[1])%(b[0]-a[1]);
return a[0]+_1/(_1+_2)*a.v();
}

真 · 直线相交

inline Pt Cross(Line a, Line b){
return a[0]+(b.v()%(a[0]-b[0])/(a.v()%b.v()))*a.v();
}

多边形的定义

struct Poly{
Pt p[MAXN+5]; int n;
inline void clear(){n=0;}
inline Pt& operator[](int i){return p[i];}
inline Pt& back(){return p[n];}
inline void push(Pt o){p[++n] = o;}
inline void pop(){--n;}
db Area(){
if(n<3) return 0; static db _; _ = 0;
p[n+1] = p[1]; for(rint i = 1; i <= n; _ = _+p[i]%p[i+1], i++);
return fabs(_)/2;
}
};

多边形的定义

typedef vector<Pt> Poly;

基本(2D)解析几何

直线相交

\begin{aligned} y = k_1 x + b_1 \\ y = k_2 x + b_2 \\ \end{aligned} \\ x = \frac{b_2-b_1}{k_1-k_2} \\ y = k_1x + b_1 \\

关于直线的对称点

\begin{aligned} & (x,y) \\ \xrightarrow{Ax+By+C=0} & (x,y)-2d(\cos \theta, \sin \theta) \\ = & (x,y)-2\frac{Ax_0+By_0+C}{A^2+B^2}(A,B) \end{aligned}
d = \frac{Ax_0+By_0+C}{\sqrt{A^2+B^2}}

解析几何的基本结论

\frac{a}{\sin A} = \frac{b}{\sin B} = \frac{c}{\sin C} = 2r_{\text{circumcircle}}
\begin{aligned} a^2 &= b^2+c^2 - 2bc\cos A \\ b^2 &= a^2+c^2 - 2ac\cos B \\ c^2 &= a^2+b^2 - 2ab\cos C \\ \end{aligned}

解析几何的基本结论

\begin{aligned} & p \equiv \frac{1}{2}C_{\Delta ABC} = \frac{a+b+c}{2} \\ & S_{\Delta ABC} = \sqrt{p(p-a)(p-b)(p-c)} \end{aligned}

解析几何的基本结论

\begin{aligned} CD^2 = AD \cdot BD \\ BC^2 = BD \cdot BA \\ AC^2 = AD \cdot AB \\ a = b \cos C + c \cos B \\ b = a \cos C + c \cos A \\ c = a \cos B + b \cos A \\ \end{aligned}

角度的计算

\cos \langle \vec a, \vec b \rangle = \frac{\vec a \cdot \vec b}{\vert \vec a \vert \vert \vec b \vert}
\cos A = \frac{b^2+c^2-a^2}{2bc}
atan2(y,x)
\in (-\pi,\pi]

圆

Situation #Common Tangents
0
1
2
3
4
0 \le d \lt \vert r_1 - r_2 \vert
d = \vert r_1 - r_2 \vert
\vert r_1 - r_2 \vert \lt d \lt r_1+r_2
d = r_1+r_2
r_1+r_2 \lt d

进阶(2D)计算几何

角度的比较

inline bool Para(Vec a, Vec b){return fabs(a%b) <= EPS;}
inline bool ToLeft(Vec a, Vec b){return b%a > EPS;}

inline bool operator < (Line a, Line b){
return Para(a.v(),b.v()) && a.v()*b.v() > EPS ? ToLeft(a[0]-b[0],b.v()) : cmpang(a.v(),b.v());
}

Convex-Up

Concave-Up

求凸包

struct Vec{
//...
inline bool operator < (Vec b){return fabs(y-b.y) <= EPS ? x < b.x : y < b.y;}
};  typedef Vec Pt;

//      Unstrict      <==>      Strict
//  !ToLeft(yyy,xxx)        ToLeft(xxx,yyy)

// (Unstrict) ConvexHull, return a CCW CH
// Pt on edge won't be considered part of the CH, uses function "cmpltl" and Pt "LTL"

Pt LTL; inline bool cmpltl(Pt a, Pt b){return Para(a=a-LTL,b=b-LTL) ? ~a < ~b : ToLeft(b,a);}
void CH(Pt p[], int m, Poly &R){
R.clear(), LTL = *min_element(p+1,p+m+1), sort(p+1,p+m+1,cmpltl);
for(rint i = 1; i <= m; R.push(p[i++]))
for(; R.n>1 && !ToLeft(p[i]-R[R.n-1],R[R.n]-R[R.n-1]); R.pop());
}

旋转卡壳

db RC(Poly &R, db Ans=0){
for(rint i = (R[R.n+1] = R[1], 1), j = 2; i <= R.n; Ans = max(Ans,~(R[j]-R[i])), i++)
for(; (R[i+1]-R[i])%(R[j]-R[i]) < (R[i+1]-R[i])%(R[j+1]-R[i]); j = j%R.n+1); return sqrt(Ans);
}

Minkowski和

// Notice that the indices are 0-based
void Minkowski(Poly &A, Poly &B, Poly &R){
rint i = 0, j = 0; R.clear(), R.push_back(A[0]+B[0]);
for(; ;){
p = ToLeft(A[-~i%A.size()]-A[i],B[-~j%B.size()]-B[j]) ?
A[i]+B[++j%=B.size()]
:
A[++i%=A.size()]+B[j];
R.size()>1&&Para(p-R.back(),R.back()-R[R.size()-2]) ?
R.pop_back(),0 : 0;
R.push_back(p); if(!i&&!j) break;
}   R.pop_back();
}

rotate(p+1,min_element(p+1,p+n+1),p+n+1);

点与多边形位置关系

// Angle ∠AKB
inline db Angle(Pt A, Pt B, Pt K){
static db _; B = B-K, A = A-K, _ = atan2(B.y,B.x)-atan2(A.y,A.x),
_<=-PI-EPS?_+=2*PI:0, _>=PI+EPS?_-=2*PI:0; return _;
}
inline db SumAngle(Poly &R, Pt p){
static db _; _ = 0;
for(rint i = 0; i < R.size(); _ += Angle(R[i],R[-~i%n],p), i++);
return _;
}
// ...

puts(fabs(SumAngle(R,p))>=EPS?"Yes":"No"));

点与多边形位置关系

// Pt on edge would be considered part of the CH

bool Q(Poly &E, Pt p){
int _ = lower_bound(E.begin(),E.end()-1,p,cmpltl)-E.begin();
return !ToLeft(E[_]-E[~-_],p-E[~-_]);
}

// ...

puts(LTL==p||(LTL<p&&Q(R,p))?"Yes":"No"));

半平面交

inline bool cmpang(Vec a, Vec b){return a.Quad()^b.Quad() ? a.Quad() < b.Quad() : ToLeft(b,a);}
inline bool operator < (Line a, Line b){
return Para(a.v(),b.v()) && a.v()*b.v() > EPS ? ToLeft(a[0]-b[0],b.v()) : cmpang(a.v(),b.v());
}

// ...

// (StrictLeft) HalfPlaneIntersection, return a CCW CH
// L[] should be sorted (with Line's operator < ) before passing in
void HPI(Line L[], int m, Poly &R){
static Line q[MAXN+5]; static int head, tail; R.clear(), head = 1, q[tail=1] = L[1];
for(rint i = 2; i <= m; i++){
if(!cmpang(q[tail].v(),L[i].v())) continue;
q[++tail] = L[i];
}
q[tail+1] = q[head]; for(rint i = head; i <= tail; R.push(Cross(q[i],q[i+1])), i++);
}

KD树

#define f(x,c) t[x].c
#define lc(x) t[x].c[0]
#define rc(x) t[x].c[1]
#define c(x,y) t[x].c[y]
struct O{int x[2];}dat[MAXN+5];
struct Node{int l, d, r, u, c[2];}t[MAXN+5]; bool kd; int n, rt, mn, mx, ans;
#define dis(a,b) (abs(a.x[0]-b.x[0])+abs(a.x[1]-b.x[1])) // Manhattan Distance
inline bool cmp(O a, O b){return a.x[kd]-b.x[kd] ? a.x[kd]<b.x[kd] : a.x[!kd]<b.x[!kd];}
inline void Push(int p){
for(rint k = 0; k < 2; k++) if(c(p,k))
f(p,l) = min(f(p,l),f(c(p,k),l)), f(p,d) = min(f(p,d),f(c(p,k),d)),
f(p,r) = max(f(p,r),f(c(p,k),r)), f(p,u) = max(f(p,u),f(c(p,k),u));
}
inline int Build(int lef, int rig, int dep){
if(lef > rig) return 0; int mid = lef+rig>>1;
kd = dep&1, nth_element(dat+lef,dat+mid,dat+rig+1,cmp);
lc(mid) = Build(lef,mid-1,dep+1), rc(mid) = Build(mid+1,rig,dep+1);
f(mid,l) = f(mid,r) = dat[mid].x[0], f(mid,d) = f(mid,u) = dat[mid].x[1]; Push(mid); return mid;
}
inline int Maxdis(int p, O a){
return max(abs(a.x[0]-f(p,l)),abs(a.x[0]-f(p,r)))+max(abs(a.x[1]-f(p,d)),abs(a.x[1]-f(p,u)));
}
inline int Mindis(int p, O a){
return max(f(p,l)-a.x[0],0)+max(a.x[0]-f(p,r),0)+max(f(p,d)-a.x[1],0)+max(a.x[1]-f(p,u),0);
}
inline void QMax(int p, O a){
if(!p)  return; mx = max(mx,dis(dat[p],a));
int lv = Maxdis(lc(p),a), rv = Maxdis(rc(p),a);
if(lv > rv) lv > mx ? QMax(lc(p),a),0 : 0, rv > mx ? QMax(rc(p),a),0 : 0;
else        rv > mx ? QMax(rc(p),a),0 : 0, lv > mx ? QMax(lc(p),a),0 : 0;
}

2D树(曼哈顿距离)

KD树

struct O{int x[5];}dat[MAXN+5], o; struct Node{int c[2];}t[MAXN+5];
typedef pair<int,int> pii; priority_queue<pii> q; int K, rt, kd;
inline int dis2(O a, O b, rint ans=0){
for(rint d = 0; d < K; ans += sqr(a.x[d]-b.x[d]), d++); return ans;
}
inline bool cmp(O a, O b){return a.x[kd]-b.x[kd] ? a.x[kd]<b.x[kd] : a.x[!kd]<b.x[!kd];}
inline int Build(int lef, int rig, int dep){
if(lef > rig) return 0; int mid = lef+rig>>1;
kd = dep%K, nth_element(dat+lef,dat+mid,dat+rig+1,cmp);
lc(mid) = Build(lef,mid-1,dep+1), rc(mid) = Build(mid+1,rig,dep+1); return mid;
}
inline void Query(int p, O &a, int dep){
if(!p) return; kd = dep%K; int v = dis2(dat[p],a), r = cmp(dat[p],a); Query(c(p,r),a,dep+1);
if(q.size()<M) q.push(pii(v,p)); else if(v<q.top().first) q.pop(), q.push(pii(v,p));
kd = dep%K; if(q.size()<M||sqr(dat[p].x[kd]-a.x[kd])<q.top().first) Query(c(p,!r),a,dep+1);
}

KD树(欧几里得距离)

进阶(2D)解析几何

圆反演

T = T^{-1}
T(P) = P' \text{ where } O \in PP', \vert OP \vert \vert OP' \vert = r^2

\Leftrightarrow

\Leftrightarrow

(且半径之比等于到反演圆心距离之比)

(自适应)辛普森积分

inline db Integ(db l, db r){
static db m; m = (l+r)/2;
return (r-l)/6*(F(l)+4*F(m)+F(r));
}
inline db Simpson(db l, db r, db S){
db m = (l+r)/2, a = Integ(l,m), b = Integ(m,r);
return fabs(a+b-S)<=EPS ? S+(a+b-S)/15 : Simpson(l,m,a)+Simpson(m,r,b);
}
\int_l^r f(x)\;\text{d}x \approx \frac{r-l}{6}\left(f(l)+4f(\frac{l+r}{2})+f(r)\right)
\frac{1}{15} ???

(自适应)辛普森积分

(第一次手动随机划分子区间/区间端点做微小扰动)

(3D)计算几何

混合积

a \cdot (b \times c) = \det \begin{bmatrix} a_1 & a_2 & a_3 \\ b_1 & b_2 & b_3 \\ c_1 & c_2 & c_3 \\ \end{bmatrix}

a,b,c三个向量构成的平行六面体有向体积为

a \cdot (b \times c)

b,c两个向量确定的平面法向量为

(\vec i, \vec j, \vec k) \cdot (b \times c)

\frac{1}{2} \vert (\vec i, \vec j, \vec k) \cdot (b \times c) \vert

Fun Problem Time!

POJ 2242

d_{\text{circumcircle}} = \frac{a}{\sin A} = \frac{a}{\frac{\vert \vec b \times \vec c \vert}{bc}} = \frac{abc}{\vert \vec b \times \vec c \vert}

BZOJ 1502

x_i = \frac{\sum_{j=1}^i h_j}{\tan \alpha}

BZOJ 1502

x_i = \frac{\sum_{j=1}^i h_j}{\tan \alpha}

BZOJ 1502

x_i = \frac{\sum_{j=1}^i h_j}{\tan \alpha}

BZOJ 1502

x_i = \frac{\sum_{j=1}^i h_j}{\tan \alpha}

\int_l^r f(x)\;\text{d}x \approx \frac{r-l}{6}\left(f(l)+4f(\frac{l+r}{2})+f(r)\right)

BZOJ 5317

\begin{aligned} & \text{给定两个实心凸多边形}A\text{和}B\text{，每次给出向量}v\text{，} \\ & \text{记实心多边形}C\text{为} \lbrace b+v \vert b \in B \rbrace \text{，} \\ & \text{求}A\text{和}C\text{是否有公共点。} \vert A \vert, \vert B \vert,q \le 10^5. \end{aligned}

BZOJ 5317

\exists a \in A, b \in B, b + v = a \\ \Leftrightarrow v \in A-B \\
A-B?

BZOJ 5317

\exists a \in A, b \in B, b + v = a \\ \Leftrightarrow v \in A-B \\
A-B?
A-B = A + (-B)
A+(-B)?

BZOJ 5317

\exists a \in A, b \in B, b + v = a \\ \Leftrightarrow v \in A-B \\
A-B?
A-B = A + (-B)
A+(-B)?

Minkowski和

BZOJ 5317

\exists a \in A, b \in B, b + v = a \\ \Leftrightarrow v \in A-B \\
A-B?
A-B = A + (-B)
A+(-B)?

Minkowski和

BZOJ 5317

\exists a \in A, b \in B, b + v = a \\ \Leftrightarrow v \in A-B \\
A-B?
A-B = A + (-B)
A+(-B)?

Minkowski和

POJ 3301

\begin{aligned} & \text{给定平面上}n\text{个点，求最小正方形覆盖。} \\ & n \le 30 \\ \end{aligned}

POJ 3301

$$n$$特别小，可以随便乱搞

UOJ 326

\begin{aligned} & \text{给定平面上}n\text{个红点和}m\text{个蓝点，} \\ & \text{对于每对红点}P_iP_j\text{，求:} \\ & \Delta OP_iP_j\text{内是否有至少一个蓝点，} \\ & \text{输出任意一个蓝点或}-1\text{。} \\ & n,m \le 4000 \end{aligned}

Codeforces 889D

\begin{aligned} & \text{给定平面上}n\text{个点，求有多少条过原点的直线满足:} \\ & \text{这条直线上投影点的可重集关于某个点中心对称。} \\ & n \le 2000 \\ \end{aligned}

Codeforces 889D

\begin{aligned} & \text{给定球面上顺序}n\text{个点，相邻两点之间走球面最短路，} \\ & \text{判断是否任何大圆都经过这条回路(接触也算作经过)。} \\ & n \le 5000, T \le 200. \\ \end{aligned}

\sqrt{}

O(Tn^3)

\sqrt{}

O(Tn^3)
random_shuffle(p+1,p+n+1)

\sqrt{}

O(Tn^3)
random_shuffle(p+1,p+n+1)

TopCoder 10308

\begin{aligned} & \text{给定两个凸包}C_1, C_2\text{，}C_2\text{严格包含在}C_1\text{内，} \\ & \text{如果从}C_1\text{的边界上等概率选择一个点}x\text{，} \\ & \text{求从}x\text{到「}C_1\text{边界上距离}x\text{最远的点」的连线与}C_2\text{有交的概率。} \\ & \vert C_1 \vert, \vert C_2 \vert \le 50. \\ \end{aligned}

TopCoder 10308

p_i\text{什么时候会成为}\text{「}C_1\text{边界上距离}x\text{最远的点」？}

TopCoder 10308

p_i\text{什么时候会成为}\text{「}C_1\text{边界上距离}x\text{最远的点」？}
\forall p_j, \text{dis}(x,p_i) \ge \text{dis}(x,p_j)

TopCoder 10308

p_i\text{什么时候会成为}\text{「}C_1\text{边界上距离}x\text{最远的点」？}

p_i
p_i
p_i
\forall p_j, \text{dis}(x,p_i) \ge \text{dis}(x,p_j)

TopCoder 10308

p_i\text{什么时候会成为}\text{「}C_1\text{边界上距离}x\text{最远的点」？}

p_i
p_i
p_i

C_2
C_1
\forall p_j, \text{dis}(x,p_i) \ge \text{dis}(x,p_j)

ZROJ 76

\begin{aligned} & \text{有限矩形平面内给定}n{个点，} \\ & \text{求一个任意的、距离这}n{个点中} \\ & \text{「不严格第二近邻」最远的点。} \\ & n \le 1500. \\ \end{aligned}

BZOJ 1069

\begin{aligned} & \text{给定平面}n\text{个点，求选择其中的}4\text{个点，} \\ & \text{最大化所形成的四边形面积。} n \le 2000. \\ \end{aligned}

O(n^2)

BZOJ 1069

db RC(Polygon &R, db Ans=0){
for(rint l = (R[R.n+1] = R[1], 1), r, i, j; l <= R.n; l++)
for(i = l%R.n+1, r = l+2, j = r%R.n+1; r <= R.n; r++){
for(; i%R.n+1!=r && (R[i]-R[l])%(R[r]-R[l]) < (R[i+1]-R[l])%(R[r]-R[l]); i = i%R.n+1);
for(; j%R.n+1!=l && (R[j]-R[r])%(R[l]-R[r]) < (R[j+1]-R[r])%(R[l]-R[r]); j = j%R.n+1);
Ans = max(Ans,(R[i]-R[l])%(R[r]-R[l])+(R[j]-R[r])%(R[l]-R[r]));
}   return Ans/2.;
}

HDU 4773

\begin{aligned} & \text{给定两个相离的圆和一个不在圆上的点}O\text{，} \\ & \text{求所有经过该点且与两个圆都外切的圆。} \\ \end{aligned}

Codeforces 975E

\begin{aligned} & \text{给定一个凸多边形，一开始多边形的点}1\text{和}2\text{固定，} \\ & \text{每次取消某个固定点(多边形由于重力旋转到势能最低状态)，} \\ & \text{然后再将这个点固定在某个点}j\text{。} \\ & q\text{次查询某个顶点的坐标。} \\ & n \le 10^4, q \le 2 \times 10^5. \\ \end{aligned}

BZOJ 2732

\begin{aligned} & \text{给定平面上}n\text{条平行于}y\text{轴的线段，} \\ & \text{求如果做一条原点开始的抛物线}y = ax^2+bx(a \lt 0, b \gt 0)\text{，} \\ & \text{最多可以穿过前几条线段(恰好过端点也算作穿过)。} n \le 10^5. \\ \end{aligned}

BZOJ 2732

\begin{aligned} & l \le x^2a + xb \le r \\ \Leftrightarrow & b \le - x \cdot a + \frac{r}{x} \text{ and } b \ge -x \cdot a + \frac{l}{x} \end{aligned}

BZOJ 2732

\begin{aligned} & l \le x^2a + xb \le r \\ \Leftrightarrow & b \le - x \cdot a + \frac{r}{x} \text{ and } b \ge -x \cdot a + \frac{l}{x} \end{aligned}

(a,b)点集的半平面交

ZROJ 144

\begin{aligned} & \text{给定}3\text{个凸多边形，多组询问：} \\ & \text{是否可以在每个多边形内部(不严格)选择一个点，} \\ & \text{使得这三个点的重心恰好落在}(x,y)\text{。} \\ & n,m \le 10^5. \\ \end{aligned}

ZROJ 144

(\frac{x_1+x_2+x_3}{3},\frac{y_1+y_2+y_3}{3})

ZROJ 144

(\frac{x_1+x_2+x_3}{3},\frac{y_1+y_2+y_3}{3})
\exists (x,y) \in \frac{A}{3} + \frac{B}{3} + \frac{C}{3}

ZROJ 144

(\frac{x_1+x_2+x_3}{3},\frac{y_1+y_2+y_3}{3})
\exists (x,y) \in \frac{A}{3} + \frac{B}{3} + \frac{C}{3}

Minkowski和

ZROJ 144

(\frac{x_1+x_2+x_3}{3},\frac{y_1+y_2+y_3}{3})
\exists (x,y) \in \frac{A}{3} + \frac{B}{3} + \frac{C}{3}

Minkowski和

（似曾相识）

BZOJ 1100

\begin{aligned} & \text{顺序给定一个不自交多边形的顶点，求对称轴数。} \\ & n \le 10^5. \\ \end{aligned}

Mix

Mix

Mix

\Leftrightarrow
\ge n

SGU 198

\begin{aligned} & \text{给定平面上n个位置关系任意的圆，以及一个不和} \\ & \text{其他任何圆相交的圆。求这个圆能否保持和其他} \\ & \text{圆不相交的情况下，移动到无穷远处。} \\ & n \le 300. \\ \end{aligned}

Mix

Mix

Mix

Mix

Mix

Mix

SPFA判负环

Codeforces 704E

\begin{aligned} & \text{一棵树上}m\text{个事件:} \\ & \text{「一个点从}t_i\text{时刻开始以每秒}c_i\text{条边的速度从}u_i\text{移动向}v_i\text{」} \\ & \text{求最早相遇的两个点的相遇时间(可能为小数)。} \\ & n,m \le 10^5, t_i,c_i \le 10^4\text{，精度误差} \le 10^{-6}. \\ \end{aligned}

Mix

Mix

Mix

Codeforces 704E

Mix

std::set

Codeforces 704E

Mix

std::set

Codeforces 704E

Mix

std::set

BZOJ 2391

\begin{aligned} & \text{给定平面上}m\text{个有权值的点和一个多边形} \\ & \text{多次查询一个「子顶点形成的多边形」内点权和。} \\ & n,m \le 1000, q \le 10000. \\ \end{aligned}

Mix

Mix

Mix

Mix

UOJ 326 ++

n棵平衡树

Mix

UOJ 326 ++

BZOJ 5316

\begin{aligned} & \text{给定平面上}n\text{个不区分的点和一个放大了}R\text{倍的单位圆，} \\ & \text{每个点独立行动，求所有点在圆上等距分布所需最小时间。} \\ & n \le 200, \vert x_i \vert, \vert y_i \vert, \vert R \vert \le 100. \\ \end{aligned}

Mix

Mix

Mix

2n

BZOJ 5316

Mix

2n

O(m \sqrt n)
O(n^{3.5} \log R)

BZOJ 5316

Mix

2n

O(m \sqrt n)
O(n^{3.5} \log R)

O(n^{3} \log R)

Mix

Mix

Mix

Mix

Mix

（推荐手写尝试）

SGU 303

\begin{aligned} & \text{输入}n\text{条只在端点处相交的线段，线段有权值，构成闭合图形，} \\ & \text{给定两点}S,T\text{，保证}S,T\text{不在线段上或无限大区域内，} \\ & \text{求选择原图线段中的一个子集构成一个简单多边形，使得:} \\ & S\text{不可能不经过多边形边到达}T\text{，输出最小代价方案。} \\ & \text{保证有解，}n \le 300, \text{所有点坐标绝对值} \le 10^4. \\ \end{aligned}

Mix

Mix

Mix

= 对偶图最短路

Mix

= 对偶图最短路

THUWC 2019 D2T3

\begin{aligned} & \text{给定平面上}n\text{个点，从所有} \\ & \text{「以其中若干个点为顶点的凸多边形」} \\ & \text{中选出一个凸多边形，求选出的凸多边形的面积的期望和方差。} \\ & n \le 500 \\ \end{aligned}

Mix

Mix

Mix

THUWC 2019 D2T3

\begin{aligned} \sigma &= \frac{1}{n}\sum (x_i-\overline x)^2 \\ &= \frac{1}{n}\left (\sum x_i^2 \right) - \frac{2\overline x}{n}\left(\sum x_i\right) + \frac{1}{n} \left( \sum \overline x^2\right) \\ &= \frac{1}{n}\left (\sum x_i^2 \right) - \overline x^2 \\ &= \overline{x^2} - \overline x^2 \\ \end{aligned}

（即：方差 = 平方的期望 - 期望的平方）

Mix

THUWC 2019 D2T3

f[a][c][d] = \sum_b f[a][b][c] \\ g[a][c][d] = \sum_b g[a][b][c]+f[a][b][c] \cdot s_{c,d} \\ h[a][c][d] = \sum_b h[a][b][c] + 2 \cdot g[a][b][c] \cdot s_{c,d} + f[a][b][c] \cdot s_{c,d}^2 \\

Mix

THUWC 2019 D2T3

f[a][c][d] = \sum_b f[a][b][c] \\ g[a][c][d] = \sum_b g[a][b][c]+f[a][b][c] \cdot s_{c,d} \\ h[a][c][d] = \sum_b h[a][b][c] + 2 \cdot g[a][b][c] \cdot s_{c,d} + f[a][b][c] \cdot s_{c,d}^2 \\

O(n^4)

Mix

THUWC 2019 D2T3

f[a][c][d] = \sum_b f[a][b][c] \\ g[a][c][d] = \sum_b g[a][b][c]+f[a][b][c] \cdot s_{c,d} \\ h[a][c][d] = \sum_b h[a][b][c] + 2 \cdot g[a][b][c] \cdot s_{c,d} + f[a][b][c] \cdot s_{c,d}^2 \\

O(n^4)

O(n^3)
\begin{aligned} & \text{给定平面上}n\text{个点和一个多边形} \\ & \text{将多边形随机旋转一个角度，求：} \\ & \text{多边形旋转后覆盖的点数的期望。} \\ & n \le 200, m \le 500, \vert x_i \vert, \vert y_i \vert \le 10^6. \\ \end{aligned}

Mix

Mix

Mix

Mix

Mix

Mix

n \le 10

Mix

d = \frac{c_0+c_1x_1+c_2x_2+ \cdots +c_nx_n}{\sqrt{c_1^2+c_2^2+ \cdots +c_n^2}} = \frac{c_0 + c \cdot x}{\| c \|_2}

Mix

\frac{c_0 + c \cdot x_i}{\| c \|_2} = r_i
d = \frac{c_0+c_1x_1+c_2x_2+ \cdots +c_nx_n}{\sqrt{c_1^2+c_2^2+ \cdots +c_n^2}} = \frac{c_0 + c \cdot x}{\| c \|_2}

Mix

\frac{c_0 + c \cdot x_i}{\| c \|_2} = r_i
d = \frac{c_0+c_1x_1+c_2x_2+ \cdots +c_nx_n}{\sqrt{c_1^2+c_2^2+ \cdots +c_n^2}} = \frac{c_0 + c \cdot x}{\| c \|_2}

n个方程，n+1个变量？

Mix

\frac{c_0 + c \cdot x_i}{\| c \|_2} = r_i
d = \frac{c_0+c_1x_1+c_2x_2+ \cdots +c_nx_n}{\sqrt{c_1^2+c_2^2+ \cdots +c_n^2}} = \frac{c_0 + c \cdot x}{\| c \|_2}

n个方程，n+1个变量？

\| c \|_2