传送门
边分治+闵可夫斯基和即可(注意要处理lca的情况
简单易懂,我们赢了(滑稽保命
代码:
#include<bits/stdc++.h>
#define ri register int
#define fi first
#define se second
using namespace std;
const int rlen=1<<18|1;
inline char gc(){
static char buf[rlen],*ib,*ob;
(ib==ob)&&(ob=(ib=buf)+fread(buf,1,rlen,stdin));
return ib==ob?-1:*ib++;
}
inline int read(){
int ans=0;
bool f=1;
char ch=gc();
while(!isdigit(ch))f^=ch=='-',ch=gc();
while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
return f?ans:-ans;
}
typedef long long ll;
typedef pair<int,int> pii;
const int N=5e5+5,inf=0x3f3f3f3f;
vector<int>g[N],Son[N],e[N];
int va[N],vb[N],typ[N],n,m,qr,siz[N],all,Fa[N],ft[N];
pii Rt;
struct pot{
ll x,y;
pot(ll x=0,ll y=0):x(x),y(y){}
friend inline pot operator+(const pot&a,const pot&b){return pot(a.x+b.x,a.y+b.y);}
friend inline pot operator-(const pot&a,const pot&b){return pot(a.x-b.x,a.y-b.y);}
friend inline ll operator^(const pot&a,const pot&b){return a.x*b.y-a.y*b.x;}
friend inline bool operator<(const pot&a,const pot&b){return a.x^b.x?a.x<b.x:a.y<b.y;}
};
vector<pot>ptt,pt[2][2];
bool vis[N];
inline void graham(vector<pot>&a){
static int top=0,q[N],n;
top=0,n=a.size()-1;
sort(a.begin(),a.end());
for(ri i=0;i<=n;++i){
while(top>1&&((a[i]-a[q[top]])^(a[q[top]]-a[q[top-1]]))<=0)--top;
q[++top]=i;
}
for(ri i=1;i<=top;++i)a[i-1]=a[q[i]];
a.resize(top);
}
inline void Msum(vector<pot>a,vector<pot>b){
if(!a.size()||!b.size())return;
graham(a),graham(b);
ptt.push_back(a[0]+b[0]);
int n=a.size()-1,m=b.size()-1,p1=0,p2=0;
pot ta,tb;
while(p1<n&&p2<m){
ta=a[p1+1]-a[p1],tb=b[p2+1]-b[p2];
if((ta^tb)<=0)ptt.push_back(ptt.back()+ta),++p1;
else ptt.push_back(ptt.back()+tb),++p2;
}
while(p1<n)ptt.push_back(ptt.back()+a[p1+1]-a[p1]),++p1;
while(p2<m)ptt.push_back(ptt.back()+b[p2+1]-b[p2]),++p2;
}
void dfs(int p,int fa){
for(ri i=0,v;i<g[p].size();++i){
if((v=g[p][i])==fa)continue;
dfs(v,p),Son[p].push_back(v);
}
}
bool chs[N];
void dfs1(int p,int fa,int sz){
siz[p]=1;
for(ri t,i=0,v;i<e[p].size();++i){
if((v=e[p][i])==fa||vis[v])continue;
dfs1(v,p,sz),siz[p]+=siz[v];
if((t=max(siz[v],sz-siz[v]))<all)all=t,Rt=pii(p,v);
}
}
void dfs2(int p,int fa,pot dis,int op){
bool ff=chs[ft[p]];
if(!ff)chs[ft[p]]=1,dis=dis+pot(va[ft[p]],vb[ft[p]]);
if(~typ[p])pt[op][typ[p]].push_back(dis);
for(ri i=0,v;i<e[p].size();++i){
if((v=e[p][i])==fa||vis[v])continue;
dfs2(v,p,dis,op);
}
chs[ft[p]]=ff;
}
void Dfs(int p,int sz){
all=inf;
dfs1(p,0,sz);
if(all==inf)return;
int a=Rt.fi,b=Rt.se;
for(ri i=0;i<2;++i)for(ri j=0;j<2;++j)pt[i][j].clear();
if(Fa[a]==b){
chs[ft[b]]=1;
dfs2(a,b,pot(0,0),0);
dfs2(b,a,pot(va[ft[b]],vb[ft[b]]),1);
chs[ft[b]]=0;
}
else{
chs[ft[a]]=1;
dfs2(b,a,pot(0,0),1);
dfs2(a,b,pot(va[ft[a]],vb[ft[a]]),0);
chs[ft[a]]=0;
}
Msum(pt[0][0],pt[1][1]),Msum(pt[0][1],pt[1][0]);
vis[b]=1,Dfs(a,sz-siz[b]),vis[b]=0;
vis[a]=1,Dfs(b,siz[b]),vis[a]=0;
}
void rebuild(){
for(ri v1,v2,i=1,up;i<=m;++i){
up=Son[i].size();
if(up<3){
for(ri j=0;j<up;++j){
e[i].push_back(Son[i][j]);
e[Son[i][j]].push_back(i);
Fa[Son[i][j]]=i;
}
}
else{
typ[v1=++m]=-1;
e[i].push_back(v1),e[v1].push_back(i);
Fa[v1]=i,ft[v1]=ft[i];
typ[v2=++m]=-1;
e[i].push_back(v2),e[v2].push_back(i);
Fa[v2]=i,ft[v2]=ft[i];
for(ri j=0;j<up;++j)Son[j&1?v1:v2].push_back(Son[i][j]);
}
}
}
inline ll query(int k){
int n=ptt.size()-1;
ll ret=-1e18;
pot t=pot(-1,k);
if(ptt.size()<=10){
for(ri i=0;i<=n;++i)ret=max(ret,(ptt[i]^t));
return ret;
}
if(((ptt[1]-ptt[0])^t)<=0)return ptt[0]^t;
if(((ptt[n]-ptt[n-1])^t)>=0)return ptt[n]^t;
int L=1,R=n-1;
while(L<=R){
int mid=(L+R)>>1;
bool f1=((ptt[mid+1]-ptt[mid])^t)<=0,f2=((ptt[mid]-ptt[mid-1])^t)<=0;
if(f1^f2)return ptt[mid]^t;
if(f1&&f2)R=mid-1;
else L=mid+1;
}
}
int main(){
#ifdef ldxcaicai
freopen("lx.in","r",stdin);
freopen("lx.out","w",stdout);
#endif
n=m=read(),qr=read();
for(ri i=1;i<=n;++i)va[i]=read();
for(ri i=1;i<=n;++i)vb[i]=read();
for(ri i=1;i<=n;++i)typ[i]=read(),ft[i]=i;
for(ri i=1,u,v;i<n;++i){
u=read(),v=read();
g[u].push_back(v);
g[v].push_back(u);
}
dfs(1,0);
rebuild();
Dfs(1,m);
graham(ptt);
while(qr--)cout<<query(read())<<'\n';
return 0;
}