求助
  • 板块P5114 八月脸
  • 楼主Smallbasic
  • 当前回复1
  • 已保存回复1
  • 发布时间2022/12/11 11:49
  • 上次更新2023/10/24 08:00:47
查看原帖
求助
98096
Smallbasic楼主2022/12/11 11:49

点分治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;
}
2022/12/11 11:49
加载中...