点分治88分是什么情况啊。一直WA#5和#8,人要麻了。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
char buf[1 << 15], *p1 = buf, *p2 = buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,121,stdin),p1==p2)?EOF:*p1++)
const int N = 1e5 + 5;
int n, m;
inline int read() {
register int s = 0, f = 1; register char ch = getchar();
while (!isdigit(ch)) f = (ch == '-' ? -1 : 1), ch = getchar();
while (isdigit(ch)) s = (s << 1) + (s << 3) + (ch & 15), ch = getchar();
return s * f;
}
inline ll max_(ll a, ll b) { return a > b ? a : b; }
struct node {
int x, y;
inline node(int X, int Y) : x(X), y(Y) { }
inline node() { x = y = 0; }
inline bool operator > (const node &b) const { return x == b.x ? y > b.y : x > b.x; }
inline bool operator < (const node &b) const { return x == b.x ? y < b.y : x < b.x; }
inline bool operator == (const node &b) const { return x == b.x && y == b.y; }
inline ll mo() { return x * x + y * y; }
inline ll f(int k) { return 1ll * x * k + y; }
};
inline ll operator * (node a, node b) { return 1ll * a.x * b.x + 1ll * a.y * b.y; }
inline ll operator ^ (node a, node b) { return 1ll * a.x * b.y - 1l * a.y * b.x; }
inline node operator + (node a, node b) { return node(a.x + b.x, a.y + b.y); }
inline node operator - (node a, node b) { return node(a.x - b.x, a.y - b.y); }
#define poly vector<node>
int stk[N], top;
inline poly convex(poly& a, bool fl = 0) {
int n = a.size();
if (!fl) sort(a.begin(), a.end());
if (n <= 2) return a;
top = 0; poly res;
for (int i = 0; i < n; ++i) {
if (i < n - 1 && a[i].x == a[i + 1].x) continue;
while (top > 1 && ((a[i] - a[stk[top - 1]]) ^ (a[stk[top]] - a[stk[top - 1]])) <= 0) --top;
stk[++top] = i;
}
for (int i = 1; i <= top; ++i) res.push_back(a[stk[i]]);
return res;
}
inline poly minkowski(poly a, poly b) {
int n = a.size(), m = b.size();
if (!n) return b;
if (!m) return a;
poly res; int i = 0, j = 0; res.push_back(a[0] + b[0]);
while (i < n - 1 && j < m - 1)
res.push_back((((a[i + 1] - a[i]) ^ (b[j + 1] - b[j])) <= 0) ? (a[++i] + b[j]) : (a[i] + b[++j]));
while (i < n - 1) res.push_back(a[++i] + b[j]);
while (j < m - 1) res.push_back(a[i] + b[++j]);
return convex(res, 1);
}
inline poly merge(poly a, poly b) {
poly res; int n = a.size(), m = b.size(), i = 0, j = 0;
while (i < n || j < m) {
if (i < n && (j >= m || a[i] < b[j])) res.push_back(a[i++]);
else res.push_back(b[j++]);
} return convex(res, 1);
}
struct edge {
int head, to, nxt;
} ed[N << 1];
int en = 0;
inline void addedge(int from, int to) {
ed[++en].to = to; ed[en].nxt = ed[from].head; ed[from].head = en;
}
int dis[N], siz[N], vis[N], root, f[N], col[N], a[N], b[N];
inline int max_(int a, int b) {
return a > b ? a : b;
}
inline void getrt(int now, int fa, int sum) {
// cerr << "GETRT : " << now << ' ' << f[0] << endl;
siz[now] = 1; f[now] = 0;
for (int i = ed[now].head; i; i = ed[i].nxt) {
int v = ed[i].to;
if (v != fa && !vis[v]) {
getrt(v, now, sum);
siz[now] += siz[v];
f[now] = max_(f[now], siz[v]);
}
} f[now] = max_(f[now], sum - siz[now]);
if (f[root] > f[now]) root = now;
}
poly ans;
poly B, w;
struct Subt {
poly b, w, ans;
int siz;
inline Subt() { }
inline Subt(poly B, poly W, poly A, int S) : b(B), w(W), ans(A), siz(S) { }
inline bool operator > (const Subt &b) const { return siz > b.siz; }
inline bool operator < (const Subt &b) const { return siz < b.siz; }
};
priority_queue<Subt, vector<Subt>, greater<Subt> > q;
inline void getdis(int now, int sa, int sb, int fa) {
siz[now] = 1;
if (col[now]) B.push_back(node(sa, sb));
else w.push_back(node(sa, sb));
for (int i = ed[now].head; i; i = ed[i].nxt) {
int v = ed[i].to;
if (vis[v] || v == fa) continue;
getdis(v, sa + a[v], sb + b[v], now);
siz[now] += siz[v];
}
}
poly nul;
inline poly calc() {
// cerr << "CALC : " << root << endl;
while (!q.empty()) q.pop();
for (int i = ed[root].head; i; i = ed[i].nxt) {
int v = ed[i].to; if (vis[v]) continue;
int l = top; B.clear(); w.clear();
getdis(v, a[root] + a[v], b[root] + b[v], root);
// cerr << "v : " << v << ' ' << B.size() << ' ' << w.size() << endl;
B = convex(B); w = convex(w);
q.push(Subt(B, w, col[root] ? w : B, siz[v]));
}
while (q.size() >= 2) {
Subt x, y;
x = q.top(); q.pop();
y = q.top(); q.pop();
for (int i = 0; i < x.b.size(); ++i) {
x.b[i].x -= a[root], x.b[i].y -= b[root];
}
for (int i = 0; i < x.w.size(); ++i) {
x.w[i].x -= a[root]; x.w[i].y -= b[root];
}
x.ans = merge(merge(x.ans, y.ans), merge(minkowski(x.b, y.w), minkowski(x.w, y.b)));
for (int i = 0; i < x.b.size(); ++i) {
x.b[i].x += a[root], x.b[i].y += b[root];
}
for (int i = 0; i < x.w.size(); ++i) {
x.w[i].x += a[root]; x.w[i].y += b[root];
}
x.b = merge(x.b, y.b);
x.w = merge(x.w, y.w);
x.siz = x.siz + y.siz;
q.push(x);
} //if (q.size()) ans = merge(ans, q.top().ans);
if (q.empty()) return nul;
return q.top().ans;
}
inline bool operator > (poly& a, poly& b) {
return a.size() > b.size();
}
inline bool operator < (poly &a, poly &b) {
return a.size() < b.size();
}
inline poly dfs(int now) {
poly res = calc(); priority_queue<poly, vector<poly>, greater<poly> > p;
p.push(res);
vis[now] = 1;
for (int i = ed[now].head; i; i = ed[i].nxt) {
int v = ed[i].to; if (vis[v]) continue;
root = 0;
getrt(v, now, siz[v]);
p.push(dfs(root));
} poly x, y;
while (p.size() >= 2) {
x = p.top(); p.pop();
y = p.top(); p.pop();
p.push(merge(x, y));
} if (p.empty()) return nul;
return p.top();
}
struct Query {
int x, id;
} qaq[N];
inline bool cmp(Query a, Query b) {
return a.x < b.x;
}
ll res[N];
inline void otp(ll x) {
(x >= 10) ? otp(x / 10), putchar((x % 10) ^ 48) : putchar(x ^ 48);
}
int main() {
// freopen("byl.in", "r", stdin); freopen("byl2.out", "w", stdout);
n = read(); m = read();
for (int i = 1; i <= n; ++i) a[i] = read();
for (int i = 1; i <= n; ++i) b[i] = read();
for (int i = 1; i <= n; ++i) col[i] = read();
for (int i = 1, u, v; i < n; ++i) {
u = read(); v = read();
addedge(u, v); addedge(v, u);
} f[0] = 19260817;
getrt(1, 0, n); ans = dfs(root);
int p = 0;
for (int i = 1; i <= m; ++i) qaq[i].x = read(), qaq[i].id = i;
sort(qaq + 1, qaq + m + 1, cmp);
for (int i = 1; i <= m; ++i) {
while (p < ans.size() - 1 && ans[p + 1].f(qaq[i].x) >= ans[p].f(qaq[i].x))
++p;
res[qaq[i].id] = ans[p].f(qaq[i].x);
}
for (int i = 1; i <= m; ++i) {
if (res[i] < 0) putchar('-'), res[i] = -res[i];
otp(res[i]); putchar('\n');
}
return 0;
}