题解已经写在标题上了
不过复杂度能过也是神了
#include<bits/stdc++.h>
using namespace std;
const int RLEN=(1<<20)|5;
inline char gc(){
static char ibuf[RLEN],*ib,*ob;
(ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
return (ib==ob)?EOF:*ib++;
}
#define gc getchar
inline int read(){
char ch=gc();
int res=0,f=1;
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
return f?res:-res;
}
#define pb push_back
#define re register
#define fi first
#define se second
#define pii pair<int,int>
#define cs const
#define bg begin
#define ll long long
template<class tp>inline void chemx(tp &a,tp b){a<b?a=b:0;}
template<class tp>inline void chemn(tp &a,tp b){a>b?a=b:0;}
cs int N=30005;
char xxx;
cs double eps=1e-7;
struct pt{
double x,y;
pt(double a=0,double b=0):x(a),y(b){}
friend inline pt operator -(cs pt &a,cs pt &b){
return pt(a.x-b.x,a.y-b.y);
}
friend inline double operator *(cs pt &a,cs pt &b){
return a.x*b.y-a.y*b.x;
}
friend inline bool operator <(cs pt &a,cs pt &b){
return a.x==b.x?a.y<b.y:a.x<b.x;
}
inline double K(){
return y/x;
}
};
int idx[N];
double x[N],y[N],p[N],q[N];
pt qq[N];
inline vector<pt> gettb(vector<pt> tt){
sort(tt.bg(),tt.end());
int top=0;qq[top=1]=tt[0];
for(int i=1;i<tt.size();i++){
while(top>1&&(qq[top]-qq[top-1])*(tt[i]-qq[top-1])>=0)top--;
qq[++top]=tt[i];
}
vector<pt> now;
for(int i=1;i<=top;i++)now.pb(qq[i]);
return now;
}
inline double ask(cs vector<pt> &tt,double k){
int l=1,r=tt.size()-1,res=0;
while(l<=r){
int mid=(l+r)>>1;
if((tt[mid]-tt[mid-1]).K()>=k)l=mid+1,res=mid;
else r=mid-1;
}
return tt[res].y-tt[res].x*k;
}
struct data{
double a,b;
data(double _a=0,double _b=0):a(_a),b(_b){}
friend inline data operator +(cs data &a,cs data &b){
return data(max(a.a,b.a),max(a.b,b.b));
}
};
namespace Seg{
vector<pt> tr[2][N<<2];
#define lc (u<<1)
#define rc ((u<<1)|1)
#define mid ((l+r)>>1)
void build(int u,int l,int r){
vector<pt>now;
for(int i=l;i<=r;i++)now.pb(pt(x[idx[i]],y[idx[i]]));
tr[0][u]=gettb(now);now.clear();
for(int i=l;i<=r;i++)now.pb(pt(p[idx[i]],q[idx[i]]));
tr[1][u]=gettb(now);
if(l==r)return;
build(lc,l,mid),build(rc,mid+1,r);
}
data query(int u,int l,int r,int st,int des,double k){
// cerr<<u<<" "<<l<<" "<<r<<" "<<st<<" "<<des<<'
';
if(st<=l&&r<=des)return data(ask(tr[0][u],k),ask(tr[1][u],k));
if(des<=mid)return query(lc,l,mid,st,des,k);
if(st>mid)return query(rc,mid+1,r,st,des,k);
return query(lc,l,mid,st,des,k)+query(rc,mid+1,r,st,des,k);
}
#undef lc
#undef rc
#undef mid
}
vector<int> e[N];
int in[N],dfn,siz[N],son[N],top[N],fa[N],dep[N];
int n,m;
double mx;
void dfs1(int u){
siz[u]=1;
for(int &v:e[u]){
if(v==fa[u])continue;
fa[v]=u,dep[v]=dep[u]+1;
dfs1(v),siz[u]+=siz[v];
if(siz[v]>siz[son[u]])son[u]=v;
}
}
void dfs2(int u,int tp){
top[u]=tp,in[u]=++dfn,idx[dfn]=u;
if(son[u])dfs2(son[u],tp);
for(int &v:e[u]){
if(v==fa[u]||v==son[u])continue;
dfs2(v,v);
}
}
inline double pathquery(int u,int v,double k){
data now(-1e9,-1e9);
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]])swap(u,v);
now=now+Seg::query(1,1,n,in[top[u]],in[u],k);
u=fa[top[u]];
}
if(dep[u]<dep[v])swap(u,v);
now=now+Seg::query(1,1,n,in[v],in[u],k);
return now.a+now.b;
}
char yyy;
int main(){
n=read();
for(int i=1;i<=n;i++)scanf("%lf",&x[i]);
for(int i=1;i<=n;i++)scanf("%lf",&y[i]);
for(int i=1;i<=n;i++)scanf("%lf",&p[i]);
for(int i=1;i<=n;i++)scanf("%lf",&q[i]);
for(int i=1;i<=n;i++)chemx(mx,y[i]/x[i]),chemx(mx,q[i]/p[i]);
for(int i=1;i<n;i++){
int u=read(),v=read();
e[u].pb(v),e[v].pb(u);
}
dep[1]=1,dfs1(1),dfs2(1,1);
Seg::build(1,1,n);
m=read();
for(int i=1;i<=m;i++){
int a=read(),b=read();
double l=0,r=mx;
while(l+eps<r){
double mid=(l+r)*0.5;
if(pathquery(a,b,mid)>=0)l=mid;
else r=mid;
}
printf("%.4lf
",l);
}
}