# BZOJ3775: 点和直线（计算几何+拉格朗日乘数法）

## 题解

\begin{aligned} f(x,y) &=\sum {(a_ix+b_iy+c_i)^2\over d_i}\\ &=\sum {a_i^2x^2+b_i^2y^2+c_i^2+2a_ib_ixy+2a_ic_ix+2b_ic_iy\over d_i} \end{aligned}

$f(x,y)=x^2A^2+y^2B^2+C^2+2xyAB+2xAC+2yBC$

${\partial f\over \partial y}=2yB^2+2xAB+2BC=0$

$y={-xAB-BC\over B^2}$

$f(x,y)=\alpha x^2+\beta x+\gamma$

$\alpha=A^2-{(AB)^2\over B^2}$

$\beta=2AC-{2(AB)(BC)\over B^2}$

$\gamma=C^2-{(BC)^2\over B^2}$

$\alpha x^2+\beta x+\gamma-f(x,y)=0$

$\beta^2-4\alpha(\gamma-f(x,y))\geq 0$

$f(x,y)\geq \gamma-{\beta^2\over 4\alpha}$

$f(x,y)=\beta x+\gamma$

$$Claris$$说这种情况下答案就等于$$\gamma$$……然而我实在看不出为啥……我怎么感觉可以无限小呢……然而它要是变成负数显然不符合常理啊……有哪位鸽鸽知道为什么的么可以在下面留言哦qwq

ps：关于$$\alpha\geq 0$$的证明

$\alpha=A^2-{(AB)^2\over B^2}$

$A^2-{(AB)^2\over B^2}\geq 0$

$A^2B^2\geq (AB)^2$

$\left(\sum {a_i^2\over d_i}\right)\left(\sum {b_i^2\over d_i}\right)\geq \left(\sum {a_ib_i\over d_i}\right)^2$

//minamoto
#include<bits/stdc++.h>
#define R register
#define inline __inline__ __attribute__((always_inline))
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
R int res,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
R int len=0;R char ch;while(((ch=getc())>'9'||ch<'0'));
for(s[++len]=ch;(ch=getc())>='0'&&ch<='9';s[++len]=ch);
return s[len+1]='\0',len;
}
{
R double x=0,y=0.1,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(x=ch-'0';(ch=getc())>='0'&&ch<='9';x=x*10+ch-'0');
for(ch=='.'&&(ch=getc());ch>='0'&&ch<='9';x+=(ch-'0')*y,y*=0.1,ch=getc());
return x*f;
}
inline int getop(){R char ch;while((ch=getc())>'9'||ch<'0');return ch-'0';}
const int N=2e5+5;const double eps=1e-7;
inline int sgn(R double x){return x<-eps?-1:x>eps;}
struct node{
double aa,bb,cc,ab,bc,ac;int sz;
inline void ins(R double a,R double b,R double c,R double d){
++sz,aa+=a*a*d,bb+=b*b*d,cc+=c*c*d,ab+=a*b*d,ac+=a*c*d,bc+=b*c*d;
}
inline void del(R double a,R double b,R double c,R double d){
--sz,aa-=a*a*d,bb-=b*b*d,cc-=c*c*d,ab-=a*b*d,ac-=a*c*d,bc-=b*c*d;
}
double calc(){
if(!sz)return 0;
double invb=sgn(bb)?1.0/bb:0;
double a=aa-ab*ab*invb,b=2*ac-2*ab*bc*invb,c=cc-bc*bc*invb;
return !sgn(a)?c:c-b*b*0.25/a;
}
}q;
struct Line{
double a,b,c,d;
inline Line(){}
inline Line(R double x,R double y,R double xx,R double yy){
!sgn(x-xx)?(a=1,b=0,c=-x):(a=(yy-y)/(xx-x),b=-1,c=y-a*x);
d=1.0/(a*a+b*b);
}
}L[N];
int top,op,i;double x,y,xx,yy,res;
int main(){
//  freopen("testdata.in","r",stdin);
//  freopen("testdata.out","w",stdout);
op=getop();
switch(op){
case 0:{
L[++top]=Line(x,y,xx,yy),q.ins(L[top].a,L[top].b,L[top].c,L[top].d);
break;
}
case 1:{
break;
}
case 2:{
res=q.calc();
if(res<1e-3&&res>-1e-3)res=0;
printf("%.2lf\n",res);
break;
}
}
}
return 0;
}

posted @ 2019-04-14 14:41  bztMinamoto  阅读(352)  评论(1编辑  收藏  举报
Live2D