瞎扯的题目 最值推了我半小时 感受到了对高中数学的莫名恐惧
直接上大神题解吧
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; }
return *p1++;
}
inline void read(int &x){
char c=nc(),b=1;
for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1;
for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b;
}
const int K=21;
const int N=100005;
struct edge{
int u,v,next;
}G[N<<1];
int head[N],inum;
inline void add(int u,int v,int p){
G[p].u=u; G[p].v=v; G[p].next=head[u]; head[u]=p;
}
int n,m;
int xs[N],ys[N];
inline double calc(double A,double B,double C){
double delta=sqrt((double)B*B-4*A*C);
return (-delta-B)/2.0/A;
}
#define V G[p].v
int depth[N],fat[N][K];
inline int LCA(int u,int v){
if (depth[u]<depth[v]) swap(u,v);
for (int k=K-1;~k;k--)
if ((depth[u]-depth[v])>>k&1)
u=fat[u][k];
if (u==v) return u;
for (int k=K-1;~k;k--)
if (fat[u][k]!=fat[v][k])
u=fat[u][k],v=fat[v][k];
return fat[u][0];
}
namespace Work1{
ll x[N],y[N],xy[N],x2[N],y2[N];
inline void dfs(int u,int fa){
x[u]=x[fa]+xs[u],y[u]=y[fa]+ys[u],xy[u]=xy[fa]+xs[u]*ys[u];
x2[u]=x2[fa]+xs[u]*xs[u],y2[u]=y2[fa]+ys[u]*ys[u];
depth[u]=depth[fa]+1; fat[u][0]=fa;
for (int k=1;k<K;k++) fat[u][k]=fat[fat[u][k-1]][k-1];
for (int p=head[u];p;p=G[p].next)
if (V!=fa)
dfs(V,u);
}
inline void Query(int u,int v){
int lca=LCA(u,v),t=fat[lca][0];
int d=depth[u]+depth[v]-depth[lca]-depth[t];
ll sx=x[u]+x[v]-x[lca]-x[t];
ll sy=y[u]+y[v]-y[lca]-y[t];
ll sxy=xy[u]+xy[v]-xy[lca]-xy[t];
ll sx2=x2[u]+x2[v]-x2[lca]-x2[t];
ll sy2=y2[u]+y2[v]-y2[lca]-y2[t];
double A=sx2-(double)sx*sx/d;
double B=2.0*sx*sy/d-2.0*sxy;
double C=sy2-(double)sy*sy/d;
double S=calc(4.0,-4.0*(A+C),4.0*A*C-B*B);
printf("%.5lf\n",S);
}
inline void Solve(){
dfs(1,0);
int Q,iu,iv; read(Q);
while (Q--)
read(iu),read(iv),Query(iu,iv);
}
}
namespace Work2{
int path[N],tot; int inpath[N];
ll px[N],py[N],pxy[N],px2[N],py2[N];
inline void find(int u,int fa){
fat[u][0]=fa; depth[u]=depth[fa]+1;
for (int p=head[u];p;p=G[p].next){
if (V==fa) continue;
if (!depth[V])
find(V,u);
else
if (depth[V]<depth[u]){
for (int t=u;;t=fat[t][0]){
path[++tot]=t,inpath[t]=tot; if (t==V) break;
}
}
}
}
int cur,aa[N];
ll x[N],y[N],xy[N],x2[N],y2[N];
inline void dfs(int u,int fa){
x[u]=x[fa]+xs[u],y[u]=y[fa]+ys[u],xy[u]=xy[fa]+xs[u]*ys[u];
x2[u]=x2[fa]+xs[u]*xs[u],y2[u]=y2[fa]+ys[u]*ys[u];
depth[u]=depth[fa]+1; fat[u][0]=fa; aa[u]=cur;
for (int k=1;k<K;k++) fat[u][k]=fat[fat[u][k-1]][k-1];
for (int p=head[u];p;p=G[p].next)
if (V!=fa && !inpath[V])
dfs(V,u);
}
inline ll sum(ll *a,int l,int r){ if (l>r) return 0; return a[r]-a[l-1]; }
inline void Query(int u,int v){
if (aa[u]==aa[v]){
int lca=LCA(u,v),t=fat[lca][0];
int d=depth[u]+depth[v]-depth[lca]-depth[t];
ll sx=x[u]+x[v]-x[lca]-x[t];
ll sy=y[u]+y[v]-y[lca]-y[t];
ll sxy=xy[u]+xy[v]-xy[lca]-xy[t];
ll sx2=x2[u]+x2[v]-x2[lca]-x2[t];
ll sy2=y2[u]+y2[v]-y2[lca]-y2[t];
double A=sx2-(double)sx*sx/d;
double B=2.0*sx*sy/d-2.0*sxy;
double C=sy2-(double)sy*sy/d;
double S=calc(4.0,-4.0*(A+C),4.0*A*C-B*B);
printf("%.5lf\n",S);
return;
}
int au=aa[u],av=aa[v],p1=inpath[au],p2=inpath[av]; if (p1>p2) swap(p1,p2);
ll sx,sy,sx2,sy2,sxy; double A,B,C,S1,S2; int d;
d=depth[u]-1+depth[v]-1+p2-p1+1;
sx=x[u]+x[v]+sum(px,p1+1,p2-1);
sy=y[u]+y[v]+sum(py,p1+1,p2-1);
sxy=xy[u]+xy[v]+sum(pxy,p1+1,p2-1);
sx2=x2[u]+x2[v]+sum(px2,p1+1,p2-1);
sy2=y2[u]+y2[v]+sum(py2,p1+1,p2-1);
A=sx2-(double)sx*sx/d;
B=2.0*sx*sy/d-2.0*sxy;
C=sy2-(double)sy*sy/d;
S1=calc(4.0,-4.0*(A+C),4.0*A*C-B*B);
d=depth[u]-1+depth[v]-1+p1+tot-p2+1;
sx=x[u]+x[v]+sum(px,1,p1-1)+sum(px,p2+1,tot);
sy=y[u]+y[v]+sum(py,1,p1-1)+sum(py,p2+1,tot);
sxy=xy[u]+xy[v]+sum(pxy,1,p1-1)+sum(pxy,p2+1,tot);
sx2=x2[u]+x2[v]+sum(px2,1,p1-1)+sum(px2,p2+1,tot);
sy2=y2[u]+y2[v]+sum(py2,1,p1-1)+sum(py2,p2+1,tot);
A=sx2-(double)sx*sx/d;
B=2.0*sx*sy/d-2.0*sxy;
C=sy2-(double)sy*sy/d;
S2=calc(4.0,-4.0*(A+C),4.0*A*C-B*B);
printf("%.5lf\n",min(S1,S2));
}
inline void Solve(){
find(1,0);
for (int i=1;i<=tot;i++){
cur=path[i],dfs(path[i],0);
int u=path[i];
px[i]=px[i-1]+xs[u],py[i]=py[i-1]+ys[u],pxy[i]=pxy[i-1]+xs[u]*ys[u];
px2[i]=px2[i-1]+xs[u]*xs[u],py2[i]=py2[i-1]+ys[u]*ys[u];
}
int Q,iu,iv; read(Q);
while (Q--)
read(iu),read(iv),Query(iu,iv);
}
}
int main(){
int iu,iv;
freopen("inv.in","r",stdin);
freopen("inv.out","w",stdout);
read(n); read(m);
for (int i=1;i<=n;i++) read(xs[i]),read(ys[i]);
for (int i=1;i<=m;i++) read(iu),read(iv),add(iu,iv,++inum),add(iv,iu,++inum);
if (m==n-1)
Work1::Solve();
else
Work2::Solve();
return 0;
}