0 分求助
查看原帖
0 分求助
448887
cancan123456楼主2022/12/29 19:21
#include <cstdio>
using namespace std;
typedef long long ll;
const int N = 100005;
struct Node {
	ll w[3], x, len, f[4][4];
	int pri, lc, rc;
} node[2 * N];
int root, cnt;
int rand() {
	static int x = 1;
	return x *= 19260817;
}
ll max(ll a, ll b) {
	return a > b ? a : b;
}
int new_node(int a, int b, int c, int x) {
	cnt++;
	node[cnt].w[0] = a;
	node[cnt].w[1] = b;
	node[cnt].w[2] = c;
	node[cnt].x = x;
	node[cnt].len = x;
	for (int i = 0; i < 4; i++) {
		node[cnt].f[i][i] = node[cnt].w[i % 3] * x;
	}
	for (int i = 3; i >= 0; i--) {
		for (int j = i + 1; j < 4; j++) {
			node[cnt].f[i][j] = max(node[cnt].f[i][j - 1], node[cnt].f[i + 1][j]);
		}
	}
	node[cnt].pri = rand();
	return cnt;
}
void push_up(int p) {
	node[p].len = node[node[p].lc].len + node[p].x + node[node[p].rc].len;
	for (int i = 0; i < 4; i++) {
		for (int j = i; j < 4; j++) {
			node[p].f[i][j] = 0;
			for (int k = i; k <= j; k++) {
				node[p].f[i][j] = max(node[p].f[i][j], node[node[p].lc].f[i][k] + node[p].w[k % 3] * node[p].x + node[node[p].rc].f[k][j]);
			}
		}
	}
}
int merge(int x, int y) {
	if (x == 0 || y == 0) {
		return x | y;
	} else {
		if (node[x].pri < node[y].pri) {
			node[x].rc = merge(node[x].rc, y);
			push_up(x);
			return x;
		} else {
			node[y].lc = merge(x, node[y].lc);
			push_up(y);
			return y;
		}
	}
}
void split(int p, int k, int & x, int & y) {
	if (p == 0) {
		x = y = 0;
	} else {
		if (k <= node[node[p].lc].len) {
			y = p;
			split(node[p].lc, k, x, node[y].lc);
			push_up(y);
		} else if (k >= node[node[p].lc].len + node[p].x) {
			x = p;
			split(node[p].rc, k - node[node[p].lc].len - node[p].x, node[x].rc, y);
			push_up(x);
		} else {
			int q = new_node(node[p].w[0], node[p].w[1], node[p].w[2], node[node[p].lc].len + node[p].x - k);
			node[p].x = k - node[node[p].lc].len;
			node[q].rc = node[p].rc;
			node[p].rc = 0;
			x = p;
			y = q;
			push_up(x);
			push_up(y);
		}
	}
}
int main() {
	int n;
	scanf("%d", &n);
	int p, a, b, c, x;
	scanf("%d %d %d %d %d", &p, &a, &b, &c, &x);
	root = new_node(a, b, c, x);
	ll last = node[root].f[0][3];
	printf("%lld\n", last);
	for (int i = 2, p1, p2; i <= n; i++) {
		scanf("%d %d %d %d %d", &p, &a, &b, &c, &x);
		split(root, p, p1, p2);
		root = merge(merge(p1, new_node(a, b, c, x)), p2);
		printf("%lld\n", node[root].f[0][3] - last);
		last = node[root].f[0][3];
	}
	return 0;
}
2022/12/29 19:21
加载中...