求条,WA on #6
#include<bits/stdc++.h>
#define int long long
#define ls t[k].l
#define rs t[k].r
using namespace std;
const int N=3e5+15;
const int L=-1e5,R=1e5;
struct node
{
int h[N],to[N],ne[N],idx=0;
void add(int u,int v)
{
to[++idx]=v;
ne[idx]=h[u];
h[u]=idx;
}
}mp;
struct point
{
int costa,costb;
}p[N];
struct lc_segment_tree
{
int l,r,id;
}t[N*20];
int rt[N];
int cnt=0;
struct line
{
int k,b;
int get_y(int x)
{
return k*x+b;
}
}li[N*20];
int top=0;
int f[N];
int n;
void update(int &k,int l,int r,int loc)
{
if(!loc) return;
if(!k)
{
k=++cnt;
// k=loc;
// 1 t[k]=lc_segment_tree{0,0,t[loc].id};
}
int mid=(l+r)>>1;
// loc=t[loc].id;
if(!t[k].id)
{
t[k].id=loc;
return;
}
if(li[loc].get_y(mid)<li[t[k].id].get_y(mid))
{
swap(t[k].id,loc);
}
if(li[loc].get_y(l)<li[t[k].id].get_y(l))
{
update(ls,l,mid,loc);
}
if(li[loc].get_y(r)<li[t[k].id].get_y(r))
{
update(rs,mid+1,r,loc);
}
}
const int MAXN=1e18;
int query(int k,int l,int r,int x)
{
if(!k)
{
return MAXN;
}
if(l==r) return li[t[k].id].get_y(x);
int mid=(l+r)>>1;
int res=li[t[k].id].get_y(x);
if(x<=mid)
{
res=min(res,query(ls,l,mid,x));
}
else
{
res=min(res,query(rs,mid+1,r,x));
}
return res;
}
int merge(int l,int r,int x,int y)
{
if(!x||!y)
{
return x|y;
}
int mid=(l+r)>>1;
update(x,l,r,t[y].id);
merge(l,mid,t[x].l,t[y].l);
merge(mid+1,r,t[x].r,t[y].r);
return x;
}
void dfs(int u,int fa)
{
for(int i=mp.h[u];i!=-1;i=mp.ne[i])
{
int v=mp.to[i];
if(v==fa)
{
continue;
}
dfs(v,u);
rt[u]=merge(L,R,rt[u],rt[v]);
}
// f[u]=min(query(rt[u],L,R,p[u].costa),f[u]);
if(rt[u])
{
f[u]=query(rt[u],L,R,p[u].costa);
}else f[u]=0;
li[++top]=(line){p[u].costb,f[u]};
// t[++cnt]=(lc_segment_tree){0,u,0};
update(rt[u],L,R,top);
}
signed main()
{
memset(mp.h,-1,sizeof mp.h);
// memset(f,0x3f,sizeof f);
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>p[i].costa;
}
for(int i=1;i<=n;i++)
{
cin>>p[i].costb;
}
for(int i=1;i<n;i++)
{
int u,v;
cin>>u>>v;
mp.add(u,v);
mp.add(v,u);
}
dfs(1,0);
for(int i=1;i<=n;i++)
{
cout<<f[i]<<" ";
}
return 0;
}