Homework Introduction

/*
l~mid  mid+1~r
Max
Min
val
c.Max = max(a.Max,b.Max)
c,Min = min(a.Min,b.Min)
c.lMx = max(a.lMx,b.lMx,b.Max-a.Min)
c.rMx = max(a.rMx,b.rMx,a.Max-b.Min);
*/
#include <bits/stdc++.h>
using namespace std;
const int N = 5e4 + 5;

struct node {
	int Max, Min, lm, rm;
	friend node operator + (node a, node b) {
		node c = {-1, -1, -1, -1};
		if (a.Max == -1)
			return b;
		else if (b.Max == -1)
			return a;
		else {
			node c;
			c.Max = max(a.Max, b.Max);
			c.Min = min(a.Min, b.Min);
			c.lm = max(max(a.lm, b.lm), b.Max - a.Min);
			c.rm = max(max(a.rm, b.rm), a.Max - b.Min);
			return c;
		}
	}
} tree[N << 2];
int tag[N << 2];
int n, m, a[N], w[N];
int son[N], siz[N], fa[N], dep[N];
int top[N], id[N], cnt;
vector<int>e[N];

void pushup(int rt) {
	tree[rt] = tree[rt << 1] + tree[rt << 1 | 1];
}

void pushdown(int l, int r, int rt) {
	if (tag[rt]) {
		tag[rt << 1] += tag[rt];
		tag[rt << 1 | 1] += tag[rt];
		tree[rt << 1].Max += tag[rt];
		tree[rt << 1].Min += tag[rt];
		tree[rt << 1 | 1].Max += tag[rt];
		tree[rt << 1 | 1].Min += tag[rt];
		tag[rt] = 0;
	}
}

void build(int l, int r, int rt) {
	if (l == r) {
		tree[rt] = {w[l], w[l], 0, 0};
		return;
	}
	int mid = (l + r) >> 1;
	build(l, mid, rt << 1);
	build(mid + 1, r, rt << 1 | 1);
	pushup(rt);
}

void update(int l, int r, int rt, int L, int R, int c) {
	if (L <= l && r <= R) {
		tag[rt] += c;
		tree[rt].Max += c;
		tree[rt].Min += c;
		return;
	}
	pushdown(l, r, rt);
	int mid = (l + r) >> 1;
	if (L <= mid)
		update(l, mid, rt << 1, L, R, c);
	if (R > mid)
		update(mid + 1, r, rt << 1 | 1, L, R, c);
	pushup(rt);
}

node query(int l, int r, int rt, int L, int R) {
	if (L <= l && r <= R) {
		return tree[rt];
	}
	pushdown(l, r, rt);
	node res = {-1, -1, -1, -1};
	int mid = (l + r) >> 1;
	if (L <= mid)
		res = res + query(l, mid, rt << 1, L, R);
	if (R > mid)
		res = res + query(mid + 1, r, rt << 1 | 1, L, R);
	return res;
}

void dfs1(int x, int f, int deep) {
	dep[x] = deep;
	fa[x] = f;
	int maxx = 0;
	siz[x] = 1;
	for (auto v : e[x]) {
		if (v == f)
			continue;
		dfs1(v, x, deep + 1);
		siz[x] += siz[v];
		if (siz[v] > maxx) {
			maxx = siz[v];
			son[x] = v;
		}
	}
}

void dfs2(int x, int topfa) {
	id[x] = ++cnt;
	top[x] = topfa;
	w[cnt] = a[x];
	if (!son[x])
		return;
	dfs2(son[x], topfa);
	for (auto v : e[x]) {
		if (v == son[x] || v == fa[x])
			continue;
		dfs2(v, v);
	}
}

void Q1(int x, int y, int z) {
	while (top[x] != top[y]) {
		if (dep[top[x]] > dep[top[y]])
			swap(x, y);
		update(1, n, 1, id[top[y]], id[y], z);
		y = fa[top[y]];
	}
	if (dep[x] > dep[y])
		swap(x, y);
	update(1, n, 1, id[x], id[y], z);
}

node Q2(int x, int y) {
	node ansx = {-1, -1, -1, -1}, ansy = {-1, -1, -1, -1};
	while (top[x] != top[y]) {
		//	cout << x << " " << y << endl;
		if (dep[top[x]] > dep[top[y]]) {
			node tmp = query(1, n, 1, id[top[x]], id[x]);
			swap(tmp.lm, tmp.rm);
			ansx = ansx + tmp;
			x = fa[top[x]];
		} else {
			node tmp = query(1, n, 1, id[top[y]], id[y]);
			ansy = tmp + ansy;
			y = fa[top[y]];
		}
		//	cout << x << " " << y << endl;
	}
	if (dep[x] > dep[y]) {

		node tmp = query(1, n, 1, id[y], id[x]);
		swap(tmp.lm, tmp.rm);
		ansx = ansx + tmp;
	} else {
		//	cout << x << " " << id[x] << " " << y << " " << id[y] << endl;
		node tmp = query(1, n, 1, id[x], id[y]);
		ansx = ansx + tmp;
	}
	return ansx + ansy;
}

int main() {
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	for (int i = 1; i < n; i++) {
		int x, y;
		cin >> x >> y;
		e[x].push_back(y);
		e[y].push_back(x);
	}
	dfs1(1, 0, 1);
	dfs2(1, 1);
	build(1, n, 1);
	cin >> m;
	for (int i = 1; i <= m; i++) {
		int x, y, z;
		cin >> x >> y >> z;
		cout << Q2(x, y).lm << endl;
		Q1(x, y, z);
	}
	return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int n, m;

struct node {
	int lc, rc, val;
	friend node operator + (node a, node b) {
		node c = {-1, -1, -1};
		if (a.lc == -1)
			return b;
		if (b.lc == -1)
			return a;
		c.lc = a.lc;
		c.rc = b.rc;
		c.val = a.val + b.val;
		if (a.rc == b.lc)
			c.val--;
		return c;
	}
} tree[N << 2];
int tag[N << 2], a[N], dep[N], son[N], fa[N], siz[N];
int top[N], id[N], w[N], cnt;
vector<int>e[N];

void pushup(int rt) {
	tree[rt] = tree[rt << 1] + tree[rt << 1 | 1];
}

void pushdown(int rt) {
	if (tag[rt]) {
		tag[rt << 1] = tag[rt];
		tag[rt << 1 | 1] = tag[rt];
		tree[rt << 1] = {tag[rt], tag[rt], 1};
		tree[rt << 1 | 1] = {tag[rt], tag[rt], 1};
		tag[rt] = 0;
	}
}

void build(int l, int r, int rt) {
	if (l == r) {
		tree[rt] = {w[l], w[l], 1};
		return;
	}
	int mid = (l + r) >> 1;
	build(l, mid, rt << 1);
	build(mid + 1, r, rt << 1 | 1);
	pushup(rt);
}

void update(int l, int r, int rt, int L, int R, int c) {
	if (L <= l && r <= R) {
		tree[rt] = {c, c, 1};
		tag[rt] = c;
		return;
	}
	pushdown(rt);
	int mid = (l + r) >> 1;
	if (L <= mid)
		update(l, mid, rt << 1, L, R, c);
	if (R > mid)
		update(mid + 1, r, rt << 1 | 1, L, R, c);
	pushup(rt);
}

node query(int l, int r, int rt, int L, int R) {
	if (L <= l && r <= R) {
		return tree[rt];
	}
	pushdown(rt);
	node res = {-1, -1, -1};
	int mid = (l + r) >> 1;
	if (L <= mid)
		res = res + query(l, mid, rt << 1, L, R);
	if (R > mid)
		res = res + query(mid + 1, r, rt << 1 | 1, L, R);
	return res;
}

void dfs1(int x, int f, int deep) {
	dep[x] = deep;
	fa[x] = f;
	int maxx = 0;
	siz[x] = 1;
	for (auto v : e[x]) {
		if (v == f)
			continue;
		dfs1(v, x, deep + 1);
		siz[x] += siz[v];
		if (siz[v] > maxx) {
			maxx = siz[v];
			son[x] = v;
		}
	}
}

void dfs2(int x, int topfa) {
	top[x] = topfa;
	id[x] = ++cnt;
	w[cnt] = a[x];
	if (!son[x])
		return;
	dfs2(son[x], topfa);
	for (auto v : e[x]) {
		if (v == fa[x] || v == son[x])
			continue;
		dfs2(v, v);
	}
}

void pos1(int x, int y, int z) {
	while (top[x] != top[y]) {
		if (dep[top[x]] > dep[top[y]])
			swap(x, y);
		update(1, n, 1, id[top[y]], id[y], z);
		y = fa[top[y]];
	}
	if (dep[x] > dep[y])
		swap(x, y);
	update(1, n, 1, id[x], id[y], z);
}

node pos2(int x, int y) {
	node ansx = {-1, -1, -1}, ansy = {-1, -1, -1};
	while (top[x] != top[y]) {
		if (dep[top[x]] > dep[top[y]]) {
			swap(x, y);
			swap(ansx, ansy);
		}
		ansy = query(1, n, 1, id[top[y]], id[y]) + ansy;
		y = fa[top[y]];
	}
	if (dep[x] > dep[y])
		swap(x, y), swap(ansx, ansy);
	ansy = query(1, n, 1, id[x], id[y]) + ansy;
	swap(ansy.lc, ansy.rc);
	node res;
	res = ansy + ansx;
	return res;
}

int main() {
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	for (int i = 1; i < n; i++) {
		int x, y;
		cin >> x >> y;
		e[x].push_back(y);
		e[y].push_back(x);
	}
	dfs1(1, 0, 1);
	dfs2(1, 1);
	build(1, n, 1);
	while (m--) {
		char pos;
		int x, y, z;
		cin >> pos >> x >> y;
		if (pos == 'C') {
			cin >> z;
			pos1(x, y, z);
		} else {
			cout << pos2(x, y).val << endl;
		}
	}
	return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int N = 1e6+1;

struct node {
	int l, r, val;
} tree[N * 4 + 25 * N];
int n, m, a[N], tot, root[N];

void build(int l, int r, int rt) {
	if (l == r) {
		tree[rt].val = a[l];
		return;
	}
	int mid = (l + r) >> 1;
	if (!tree[rt].l)
		tree[rt].l = ++tot;
	build(l, mid, tree[rt].l);
	if (!tree[rt].r)
		tree[rt].r = ++tot;
	build(mid + 1, r, tree[rt].r);
}

void update(int l, int r, int rt, int lst, int p, int c) {
	if (l == r) {
		tree[rt].val = c;
		return;
	}
	int mid = (l + r) / 2;
	if (p <= mid) {
		//右边连谁?
		tree[rt].r = tree[lst].r;
		tree[rt].l = ++tot;
		update(l, mid, tree[rt].l, tree[lst].l, p, c);
	} else {
		tree[rt].l = tree[lst].l;
		tree[rt].r = ++tot;
		update(mid + 1, r, tree[rt].r, tree[lst].r, p, c);
	}
}

int query(int l, int r, int rt, int p) {
	if (l == r) {
		return tree[rt].val;
	}
	int mid =  (l + r) >> 1;
	if (p <= mid)
		return query(l, mid, tree[rt].l, p);
	else
		return query(mid + 1, r, tree[rt].r, p);
}

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	root[0] = ++tot;
	build(1, n, root[0]);
	for (int i = 1; i <= m; i++) {
		int opt, v, p, c;
		cin >> v >> opt >> p;
		if (opt == 1) {
			cin >> c;
			root[i] = ++tot;
			update(1, n, root[i], root[v], p, c);
		} else {
			root[i] = root[v];
			cout << query(1, n, root[i], p) << endl;
		}
	}
	return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;

struct node {
	int l, r, val;
} tree[N * 4 + N * 25];
int n, m, a[N], b[N], id[N], tot, root[N];

void pushup(int rt) {
	tree[rt].val = tree[tree[rt].l].val + tree[tree[rt].r].val;
}

/*
l~r  tree[r]-tree[l-1]
*/
void build(int l, int r, int rt) {
	if (l == r) {
		return;
	}
	int mid = (l + r) >> 1;
	tree[rt].l = ++tot;
	tree[rt].r = ++tot;
	build(l, mid, tree[rt].l);
	build(mid + 1, r, tree[rt].r);
	pushup(rt);
}

void update(int l, int r, int rt, int lst, int p, int c) {
	if (l == r) {
		tree[rt].val = tree[lst].val + c;
		return;
	}
	int mid = (l + r) >> 1;
	if (p <= mid) {
		tree[rt].r = tree[lst].r;
		tree[rt].l = ++tot;
		update(l, mid, tree[rt].l, tree[lst].l, p, c);
	} else {
		tree[rt].l = tree[lst].l;
		tree[rt].r = ++tot;
		update(mid + 1, r, tree[rt].r, tree[lst].r, p, c);
	}
	pushup(rt);
}

int query(int l, int r, int L, int R, int k) {
	if (l == r) {
		return l;
	}
	int mid = (l + r) >> 1;
	//L-R的左儿子一共有多少个数
	int D = tree[tree[R].l].val - tree[tree[L].l].val;
	if (D >= k) {
		return query(l, mid, tree[L].l, tree[R].l, k);
	} else
		return query(mid + 1, r, tree[L].r, tree[R].r, k - D);
}

int main() {
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		b[i] = a[i];
	}
	sort(b + 1, b + n + 1);
	int nn = unique(b + 1, b + n + 1) - b;
	nn--;
	for (int i = 1; i <= n; i++) {
		id[i] = lower_bound(b + 1, b + nn + 1, a[i]) - b;
	}
	build(1, nn, 1);
	for (int i = 1; i <= n; i++) {
		root[i] = ++tot;
		update(1, nn, root[i], root[i - 1], id[i], 1);
	}
	for (int i = 1; i <= m; i++) {
		int l, r, k;
		cin >> l >> r >> k;
		cout << b[query(1, nn, root[l - 1], root[r], k)] << endl;
	}
	return 0;
}
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 5;
int n, m;
double a[N];

struct node {
	double sum1, sum2;
} tree[N << 2];
double tag[N << 2];

void pushup(int rt) {
	tree[rt].sum1 = tree[rt << 1].sum1 + tree[rt << 1 | 1].sum1;
	tree[rt].sum2 = tree[rt << 1].sum2 + tree[rt << 1 | 1].sum2;
}

void pushdown(int l, int r, int rt) {
	if (tag[rt]) {
		tag[rt << 1] += tag[rt];
		tag[rt << 1 | 1] += tag[rt];
		int mid = (l + r) >> 1;
		tree[rt << 1].sum2 += 2 * tag[rt] * tree[rt << 1].sum1 + (mid - l + 1) * tag[rt] * tag[rt];
		tree[rt << 1 | 1].sum2 += 2 * tag[rt] * tree[rt << 1 | 1].sum1 + (r - mid) * tag[rt] * tag[rt];
		tree[rt << 1].sum1 += tag[rt] * (mid - l + 1);
		tree[rt << 1 | 1].sum1 += tag[rt] * (r - mid);
		tag[rt] = 0;
	}
}

void build(int l, int r, int rt) {
	if (l == r) {
		tree[rt].sum1 = a[l];
		tree[rt].sum2 = a[l] * a[l];
		return;
	}
	int mid = (l + r) >> 1;
	build(l, mid, rt << 1);
	build(mid + 1, r, rt << 1 | 1);
	pushup(rt);
}

void update(int l, int r, int rt, int L, int R, double k) {
	if (L <= l && r <= R) {
		tag[rt]+=k;
		tree[rt].sum2 += 2 * k * tree[rt].sum1 + (r - l + 1) * k * k;
		tree[rt].sum1 += k * (r - l + 1);
		return;
	}
	int mid = (l + r) >> 1;
	pushdown(l, r, rt);
	if (L <= mid)
		update(l, mid, rt << 1, L, R, k);
	if (R > mid)
		update(mid + 1, r, rt << 1 | 1, L, R, k);
	pushup(rt);
}

double query1(int l, int r, int rt, int L, int R) {
	if (L <= l && r <= R) {
		return tree[rt].sum1;
	}
	double res = 0;
	int mid = (l + r) >> 1;
	pushdown(l, r, rt);
	if (L <= mid)
		res += query1(l, mid, rt << 1, L, R);
	if (R > mid)
		res += query1(mid + 1, r, rt << 1 | 1, L, R);
	return res;
}

double query2(int l, int r, int rt, int L, int R) {
	if (L <= l && r <= R) {
		return tree[rt].sum2;
	}
	double res = 0;
	int mid = (l + r) >> 1;
	pushdown(l, r, rt);
	if (L <= mid)
		res += query2(l, mid, rt << 1, L, R);
	if (R > mid)
		res += query2(mid + 1, r, rt << 1 | 1, L, R);
	return res;
}

signed main() {
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	build(1, n, 1);
	while (m--) {
		int pos, l, r;
		double k;
		cin >> pos >> l >> r;
		if (pos == 1) {
			cin >> k;
			update(1, n, 1, l, r, k);
		} else if (pos == 2) {
			double res = query1(1, n, 1, l, r);
			cout << fixed << setprecision(4) << res / (r - l + 1) << endl;
		} else {
			int len = (r - l + 1);
			double sum1 = query1(1, n, 1, l, r);
			double sum2 = query2(1, n, 1, l, r);
			double res = sum2 / len - (sum1 * sum1) / (len * len);
			cout << fixed << setprecision(4) << res << endl;
		}
	}
	return 0;
}
/*
l~mid mid+1~r
1.tree[rt<<1].sum+tree[rt<<1|1].sum
2.tree[rt<<1].sum+tree[rt<<1|1].lmx
3.tree[rt<<1|1].sum+tree[rt<<1].rmx
4.tree[rt<<1].rmx+tree[rt<<1|1].lmx
5.tree[rt<<1].mx
6.tree[rt<<1|1].mx
*/
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 5;

struct node {
	int sum, lmx, rmx, mx;
	friend node operator + (node a, node b) {
		node c;
		c.sum = a.sum + b.sum;
		c.lmx = max(a.sum + b.lmx, a.lmx);
		c.rmx = max(b.sum + a.rmx, b.rmx);
		c.mx = max(a.sum + b.lmx, b.sum + a.rmx);
		c.mx = max(c.mx, max(a.mx, b.mx));
		c.mx = max(c.mx, a.sum + b.sum);
		c.mx = max(c.mx, a.rmx + b.lmx);
		return c;
	}
} tree[N << 2];
int n, m, a[N];

void pushup(int rt) {
	tree[rt] = tree[rt << 1] + tree[rt << 1 | 1];
}

void build(int l, int r, int rt) {
	if (l == r) {
		tree[rt] = {a[l], a[l], a[l], a[l]};
		return;
	}
	int mid = (l + r) >> 1;
	build(l, mid, rt << 1);
	build(mid + 1, r, rt << 1 | 1);
	pushup(rt);
}

void update(int l, int r, int rt, int p, int c) {
	if (l == r) {
		tree[rt] = {c, c, c, c};
		return;
	}
	int mid = (l + r) >> 1;
	if (p <= mid)
		update(l, mid, rt << 1, p, c);
	else
		update(mid + 1, r, rt << 1 | 1, p, c);
	pushup(rt);
}

node query(int l, int r, int rt, int L, int R) {
	if (L <= l && r <= R) {
		return tree[rt];
	}
	int mid = (l + r) >> 1;
	if (R <= mid)
		return query(l, mid, rt << 1, L, R);
	else if (L > mid)
		return query(mid + 1, r, rt << 1 | 1, L, R);
	else
		return query(l, mid, rt << 1, L, R) + query(mid + 1, r, rt << 1 | 1, L, R);
}

int main() {
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	build(1, n, 1);
	while (m--) {
		int pos, l, r, p, c;
		cin >> pos >> l >> r;
		if (pos == 1) {
			if (l > r)
				swap(l, r);
			cout << query(1, n, 1, l, r).mx << endl;
		} else {
			update(1, n, 1, l, r);
		}
	}
	return 0;
}
/*
l~mid mid+1
c.cnt = a.cnt+b.cnt
XXXXX(XXX  XXX)XXXXX
左边的右括号,右边的左括号
cnt,left,right
*/
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
int n, m;

struct node {
	int cnt, left, right, x;
	friend node operator + (node a, node b) {
		node c;
		c.left = b.left;
		if (b.x == 1) {
			c.left = a.left;
		}
		c.right = a.right;
		if (a.x == 1) {
			c.right = b.right;
		}
		if (a.left == 1 && b.right == 1)
			c.cnt = a.cnt + b.cnt + 1;
		else
			c.cnt = a.cnt + b.cnt;
		c.x = a.x & b.x;
		return c;
	}
} tree[N << 2];

void pushup(int rt) {
	tree[rt] = tree[rt << 1] + tree[rt << 1 | 1];
}

void build(int l, int r, int rt) {
	if (l == r) {
		tree[rt] = {0, 0, 0, 1};
		if (l == 1) {
			tree[rt] = {0, 1, 0, 0};
		} else if (l == n) {
			tree[rt] = {0, 0, 1, 0};
		}
		return;
	}
	int mid = (l + r) >> 1;
	build(l, mid, rt << 1);
	build(mid + 1, r, rt << 1 | 1);
	pushup(rt);
}

void update(int l, int r, int rt, int p, char c) {
	if (l == r) {
		if (c == 'X') {
			tree[rt] = {0, 0, 0, 1};
		} else if (c == '(') {
			tree[rt] = {0, 1, 0, 0};
		} else if (c == ')') {
			tree[rt] = {0, 0, 1, 0};
		}
		return;
	}
	int mid = (l + r) >> 1;
	if (p <= mid)
		update(l, mid, rt << 1, p, c);
	else
		update(mid + 1, r, rt << 1 | 1, p, c);
	pushup(rt);
}

node query(int l, int r, int rt, int L, int R) {
	if (L <= l && r <= R) {
		return tree[rt];
	}
	int mid = (l + r) >> 1;
	if (R <= mid)
		return query(l, mid, rt << 1, L, R);
	else if (L > mid)
		return query(mid + 1, r, rt << 1 | 1, L, R);
	else
		return query(l, mid, rt << 1, L, R) + query(mid + 1, r, rt << 1 | 1, L, R);
}

int main() {
	cin >> n >> m;
	build(1, n, 1);
	for (int i = 1; i <= m; i++) {
		int pos, l, r, x;
		char c;
		cin >> pos;
		if (pos == 1) {
			cin >> x >> c;
			update(1, n, 1, x, c);
		} else {
			cin >> l >> r;
			cout << query(1, n, 1, l, r).cnt << endl;
		}
	}
}
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5 + 5;

struct node {
	int sum, Max;
} tree[N << 2];
int a[N], n, m;

void pushup(int rt) {
	tree[rt].sum = tree[rt << 1].sum + tree[rt << 1 | 1].sum;
	tree[rt].Max = max(tree[rt << 1].Max, tree[rt << 1 | 1].Max);
}

void build(int l, int r, int rt) {
	if (l == r) {
		tree[rt] = {a[l], a[l]};
		return;
	}
	int mid = (l + r) >> 1;
	build(l, mid, rt << 1);
	build(mid + 1, r, rt << 1 | 1);
	pushup(rt);
}

void update(int l, int r, int rt, int L, int R) {
	if (tree[rt].Max == 1)
		return;
	if (l == r) {
		tree[rt].sum = sqrt(tree[rt].sum);
		tree[rt].Max = sqrt(tree[rt].Max);
		return;
	}
	int mid = (l + r) >> 1;
	if (L <= mid)
		update(l, mid, rt << 1, L, R);
	if (R > mid)
		update(mid + 1, r, rt << 1 | 1, L, R);
	pushup(rt);
}

int query(int l, int r, int rt, int L, int R) {
	if (L <= l && r <= R) {
		return tree[rt].sum;
	}
	int mid = (l + r) >> 1;
	int res = 0;
	if (L <= mid)
		res += query(l, mid, rt << 1, L, R);
	if (R > mid)
		res += query(mid + 1, r, rt << 1 | 1, L, R);
	return res;
}

signed main() {
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	cin >> m;
	build(1, n, 1);
	while (m--) {
		int pos, l, r;
		cin >> pos >> l >> r;
		if (l > r)
			swap(l, r);
		if (pos == 0) {
			update(1, n, 1, l, r);
		} else
			cout << query(1, n, 1, l, r) << endl;
	}
	return 0;
}
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 5;

struct node {
	int l, r, c;
} p[N];
int n, m, t, a[N], tree[N << 2], tag[N << 2];

bool cmp(node a, node b) {
	if (a.r == b.r)
		return a.l > b.l;
	return a.r < b.r;
}

void pushup(int rt) {
	tree[rt] = max(tree[rt << 1], tree[rt << 1 | 1]);
}

void pushdown(int rt) {
	if (tag[rt]) {
		tag[rt << 1] += tag[rt];
		tag[rt << 1 | 1] += tag[rt];
		tree[rt << 1] += tag[rt];
		tree[rt << 1 | 1] += tag[rt];
		tag[rt] = 0;
	}
}

void update(int l, int r, int rt, int L, int R, int c) {
	if (L <= l && r <= R) {
		tree[rt] += c;
		tag[rt] += c;
		return;
	}
	pushdown(rt);
	int mid = (l + r) >> 1;
	if (L <= mid)
		update(l, mid, rt << 1, L, R, c);
	if (R > mid)
		update(mid + 1, r, rt << 1 | 1, L, R, c);
	pushup(rt);
}

int query(int l, int r, int rt, int L, int R) {
	if (L <= l && r <= R) {
		return tree[rt];
	}
	pushdown(rt);
	int mid = (l + r) >> 1;
	int res = 0;
	if (L <= mid)
		res = max(res, query(l, mid, rt << 1, L, R));
	if (R > mid)
		res = max(res, query(mid + 1, r, rt << 1 | 1, L, R));
	return res;
}

signed main() {
	cin >> n >> m >> t;
	for (int i = 1; i <= n; i++) {
		cin >> p[i].l >> p[i].r >> p[i].c;
	}
	sort(p + 1, p + n + 1, cmp);
	int res = 0;
	for (int i = 1; i <= n; i++) {
		//	cout << i << endl;
		int l = p[i].l, r = p[i].r, c = p[i].c;
		int tmp = query(1, m, 1, l, r - 1);
		//	cout << i << endl;
		if (tmp + c <= t) {
			update(1, m, 1, l, r - 1, c);
			res += c;
		} else if(t-tmp>0){
			update(1, m, 1, l, r - 1, t - tmp);
			res += t - tmp;
		}
	}
	cout << res << endl;
	return 0;
}
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5 + 5;
int n, m, a[N], dep[N], siz[N], fa[N], son[N];
int cnt, top[N], id[N], wt[N];
int r, p;
int tree[N << 2], tag[N << 2];
vector<int>e[N];

void dfs1(int x, int f, int deep) {
	dep[x] = deep;
	fa[x] = f;
	siz[x] = 1;
	int maxx = 0;
	for (auto v : e[x]) {
		if (v == f)
			continue;
		dfs1(v, x, deep + 1);
		siz[x] += siz[v];
		if (siz[v] > maxx) {
			maxx = siz[v];
			son[x] = v;
		}
	}
}

void dfs2(int x, int topfa) {
	id[x] = ++cnt;
	top[x] = topfa;
	wt[cnt] = a[x];
	if (!son[x])
		return;
	dfs2(son[x], topfa);
	for (auto v : e[x]) {
		if (v == fa[x] || v == son[x])
			continue;
		dfs2(v, v);
	}
}

void pushup(int rt) {
	tree[rt] = tree[rt << 1] + tree[rt << 1 | 1];
	tree[rt] %= p;
}

void pushdown(int l, int r, int rt) {
	if (tag[rt]) {
		tag[rt << 1] += tag[rt];
		tag[rt << 1] %= p;
		tag[rt << 1 | 1] += tag[rt];
		tag[rt << 1 | 1] %= p;
		int mid = (l + r) >> 1;
		tree[rt << 1] += tag[rt] * (mid - l + 1);
		tree[rt << 1] %= p;
		tree[rt << 1 | 1] += tag[rt] * (r - mid);
		tree[rt << 1 | 1] %= p;
		tag[rt] = 0;
	}
}

void build(int l, int r, int rt) {
	if (l == r) {
		tree[rt] = wt[l];
		return;
	}
	int mid = (l + r) >> 1;
	build(l, mid, rt << 1);
	build(mid + 1, r, rt << 1 | 1);
	pushup(rt);
}

void update(int l, int r, int rt, int L, int R, int c) {
	if (L <= l && r <= R) {
		tag[rt] += c;
		tag[rt] %= p;
		tree[rt] += c * (r - l + 1);
		tree[rt] %= p;
		return;
	}
	pushdown(l, r, rt);
	int mid = (l + r) >> 1;
	if (L <= mid)
		update(l, mid, rt << 1, L, R, c);
	if (R > mid)
		update(mid + 1, r, rt << 1 | 1, L, R, c);
	pushup(rt);
}

int query(int l, int r, int rt, int L, int R) {
	if (L <= l && r <= R) {
		return tree[rt];
	}
	int mid = (l + r) >> 1;
	pushdown(l, r, rt);
	int res = 0;
	if (L <= mid)
		res += query(l, mid, rt << 1, L, R), res %= p;
	if (R > mid)
		res += query(mid + 1, r, rt << 1 | 1, L, R), res %= p;
	return res;
}

void pos1(int x, int y, int z) {
	z %= p;
	while (top[x] != top[y]) {
		if (dep[top[x]] < dep[top[y]])
			swap(x, y);
		update(1, n, 1, id[top[x]], id[x], z);
		x = fa[top[x]];
	}
	if (dep[x] > dep[y])
		swap(x, y);
	update(1, n, 1, id[x], id[y], z);
}

int pos2(int x, int y) {
	int res = 0;
	while (top[x] != top[y]) {
		if (dep[top[x]] < dep[top[y]])
			swap(x, y);
		res += query(1, n, 1, id[top[x]], id[x]);
		res %= p;
		x = fa[top[x]];
	}
	if (dep[x] > dep[y])
		swap(x, y);
	res += query(1, n, 1, id[x], id[y]);
	res%=p;
	return res;
}

void pos3(int x, int z) {
	z %= p;
	update(1, n, 1, id[x], id[x] + siz[x] - 1, z);
}

int pos4(int x) {
	return query(1, n, 1, id[x], id[x] + siz[x] - 1);
}

signed main() {
	cin >> n >> m >> r >> p;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	for (int i = 1; i < n; i++) {
		int x, y;
		cin >> x >> y;
		e[x].push_back(y);
		e[y].push_back(x);
	}
	dfs1(r, 0, 1);
	dfs2(r, r);
	build(1, n, 1);
	for (int i = 1; i <= m; i++) {
		int pos, x, y, z;
		cin >> pos;
		if (pos == 1) {
			cin >> x >> y >> z;
			pos1(x, y, z);
		} else if (pos == 2) {
			cin >> x >> y;
			cout << pos2(x, y) << endl;
		} else if (pos == 3) {
			cin >> x >> z;
			pos3(x, z);
		} else {
			cin >> x;
			cout << pos4(x) << endl;
		}
	}
	return 0;
}
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5 + 5;
vector<int>e[N];
int n, m, a[N], son[N], siz[N], fa[N], dep[N];
int top[N], tot, id[N], wt[N], root;
int tree[N << 2], tag[N << 2];

void dfs1(int x, int f, int deep) {
	dep[x] = deep;
	siz[x] = 1;
	fa[x] = f;
	int maxx = 0;
	for (auto v : e[x]) {
		if (v == f)
			continue;
		dfs1(v, x, deep + 1);
		siz[x] += siz[v];
		if (maxx < siz[v]) {
			maxx = siz[v];
			son[x] = v;
		}
	}
}

void dfs2(int x, int topfa) {
	top[x] = topfa;
	id[x] = ++tot;
	wt[tot] = a[x];
	if (!son[x])
		return;
	dfs2(son[x], topfa);
	for (auto v : e[x]) {
		if (v == fa[x] || v == son[x])
			continue;
		dfs2(v, v);
	}
}

void pushup(int rt) {
	tree[rt] = tree[rt << 1] + tree[rt << 1 | 1];
}

void pushdown(int l, int r, int rt) {
	if (tag[rt]) {
		tag[rt << 1] += tag[rt];
		tag[rt << 1 | 1] += tag[rt];
		int mid = (l + r) >> 1;
		tree[rt << 1] += tag[rt] * (mid - l + 1);
		tree[rt << 1 | 1] += tag[rt] * (r - mid);
		tag[rt] = 0;
	}
}

void build(int l, int r, int rt) {
	if (l == r) {
		tree[rt] = wt[l];
		return;
	}
	int mid = (l + r) >> 1;
	build(l, mid, rt << 1);
	build(mid + 1, r, rt << 1 | 1);
	pushup(rt);
}

void update(int l, int r, int rt, int L, int R, int c) {
	if (L <= l && r <= R) {
		tag[rt] += c;
		tree[rt] += c * (r - l + 1);
		return;
	}
	int mid =  (l + r) >> 1;
	pushdown(l, r, rt);
	if (L <= mid)
		update(l, mid, rt << 1, L, R, c);
	if (R > mid)
		update(mid + 1, r, rt << 1 | 1, L, R, c);
	pushup(rt);
}

int query(int l, int r, int rt, int L, int R) {
	if (L <= l && r <= R) {
		return tree[rt];
	}
	pushdown(l, r, rt);
	int mid = (l + r) >> 1;
	int res = 0;
	if (L <= mid)
		res += query(l, mid, rt << 1, L, R);
	if (R > mid)
		res += query(mid + 1, r, rt << 1 | 1, L, R);
	return res;
}

void pos1(int x) {
	root = x;
}

void pos2(int x, int y, int c) {
	while (top[x] != top[y]) {
		if (dep[top[x]] < dep[top[y]])
			swap(x, y);
		update(1, n, 1, id[top[x]], id[x], c);
		x = fa[top[x]];
	}
	if (dep[x] > dep[y])
		swap(x, y);
	update(1, n, 1, id[x], id[y], c);
}

int findroot(int x, int y) {
	//在x的儿子中,找到子树中含有y
	while (top[x] != top[y]) {
		y = top[y];
		if (fa[y] == x)
			return y;
		y = fa[y];
	}
	while (fa[y] != x) {
		y = fa[y];
	}
	return y;
}

void pos3(int x, int c) {
	if (x == root) {
		update(1, n, 1, 1, n, c);
	}
	//root不在x的子树里
	else if (id[root] < id[x] || id[root] > id[x] + siz[x] - 1) {
		update(1, n, 1, id[x], id[x] + siz[x] - 1, c);
	} else {
		int v = findroot(x, root);
		if (id[v] != 1) {
			update(1, n, 1, 1, id[v] - 1, c);
		}
		if (id[v] + siz[v] <= n) {
			update(1, n, 1, id[v] + siz[v], n, c);
		}
	}
}

int pos4(int x, int y) {
	int res = 0;
	while (top[x] != top[y]) {
		if (dep[top[x]] < dep[top[y]])
			swap(x, y);
		res += query(1, n, 1, id[top[x]], id[x]);
		x = fa[top[x]];
	}
	if (dep[x] > dep[y])
		swap(x, y);
	res += query(1, n, 1, id[x], id[y]);
	return res;
}

int pos5(int x) {
	if (x == root) {
		return tree[1];
	} else if (id[root] < id[x] || id[root] > id[x] + siz[x] - 1) {
		return query(1, n, 1, id[x], id[x] + siz[x] - 1);
	} else {
		int res = 0;
		int v = findroot(x, root);
		if (id[v] != 1) {
			res += query(1, n, 1, 1, id[v] - 1);
		}
		if (id[v] + siz[v] <= n) {
			res += query(1, n, 1, id[v] + siz[v], n);
		}
		return res;
	}
}

signed main() {
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	for (int i = 2; i <= n; i++) {
		int x;
		cin >> x;
		e[x].push_back(i);
		e[i].push_back(x);
	}
	dfs1(1, 0, 1);
	dfs2(1, 1);
	build(1, n, 1);
	cin >> m;
	root = 1;
	for (int i = 1; i <= m; i++) {
		int pos, x, y, z;
		cin >> pos;
		if (pos == 1) {
			cin >> x;
			pos1(x);
		} else if (pos == 2) {
			cin >> x >> y >> z;
			pos2(x, y, z);
		} else if (pos == 3) {
			cin >> x >> z;
			pos3(x, z);
		} else if (pos == 4) {
			cin >> x >> y;
			cout << pos4(x, y) << endl;
		} else if (pos == 5) {
			cin >> x;
			cout << pos5(x) << endl;
		}
	}
	return 0;
}

Problem

Please claim the assignment to see the problems.
Status
Live...
Problem
32
Open Since
2025-10-10 0:00
Deadline
2025-12-31 23:59
Extension
24 hour(s)