线段树除法求调
  • 板块灌水区
  • 楼主ka_da_Duck
  • 当前回复1
  • 已保存回复1
  • 发布时间2024/3/26 13:57
  • 上次更新2024/3/26 17:55:15
查看原帖
线段树除法求调
1088058
ka_da_Duck楼主2024/3/26 13:57

修改:区间加,区间除

查询:区间最小值,区间和

原题是这道:[雅礼集训 2017 Day1]市场

#include <bits/stdc++.h>
#define int long long

using namespace std;
const int maxn = 1e5 + 10, inf = 1e18;

int n, q;
int a[maxn];

struct node {
	int l, r, ad, val, minn, maxn;
} tr[maxn << 2];

void f(int u, int l, int r, int x) {
	tr[u].val += (r - l + 1) * x;
	tr[u].minn += x;
	tr[u].maxn += x;
	tr[u].ad += x;
}

void pushdown(int u) {
	if (!tr[u].ad) return;
	int mid = tr[u].l + tr[u].r >> 1;
	f(u << 1, tr[u].l, mid, tr[u].ad);
	f(u << 1 | 1, mid + 1, tr[u].r, tr[u].ad);
	tr[u].ad = 0;
}

void pushup(int u) {
	tr[u].minn = min(tr[u << 1].minn, tr[u << 1 | 1].minn);
	tr[u].maxn = max(tr[u << 1].maxn, tr[u << 1 | 1].maxn);
	tr[u].val = tr[u << 1].val + tr[u << 1 | 1].val;
}

void build(int u, int l, int r) {
	tr[u] = (node) {
		l, r, 0, 0, inf, 0
	};
	if (l == r) {
		tr[u].val = tr[u].minn = tr[u].maxn = a[l];
		return;
	}
	int mid = l + r >> 1;
	build(u << 1, l, mid);
	build(u << 1 | 1, mid + 1, r);
	pushup(u);
}

void add(int u, int l, int r, int x) {
	if (tr[u].l >= l && tr[u].r <= r) {
		f(u, tr[u].l, tr[u].r, x);
		return;
	}
	pushdown(u);
	int mid = tr[u].l + tr[u].r >> 1;
	if (l <= mid) add(u << 1, l, r, x);
	if (mid < r) add(u << 1 | 1, l, r, x);
	pushup(u);
}

int d(int x, int y) {
	return floor((double) x / y);
}

void chu(int u, int l, int r, int x) {
	int o = d(tr[u].maxn, x) - tr[u].maxn, p = d(tr[u].minn, x) - tr[u].minn;
	if (tr[u].l >= l && tr[u].r <= r && o == p) {
		f(u, tr[u].l, tr[u].r, o);
		return;
	}
	pushdown(u);
	int mid = tr[u].l + tr[u].r >> 1;
	if (l <= mid) add(u << 1, l, r, x);
	if (mid < r) add(u << 1 | 1, l, r, x);
	pushup(u);
}

int querymin(int u, int l, int r) {
	if (tr[u].l >= l && tr[u].r <= r) return tr[u].minn;
	pushdown(u);
	int res = inf, mid = tr[u].l + tr[u].r >> 1;
	if (l <= mid) res = min(res, querymin(u << 1, l, r));
	if (mid < r) res = min(res, querymin(u << 1 | 1, l, r));
	return res;
}

int query(int u, int l, int r) {
	if (tr[u].l >= l && tr[u].r <= r) return tr[u].val;
	pushdown(u);
	int res = 0, mid = tr[u].l + tr[u].r >> 1;
	if (l <= mid) res += query(u << 1, l, r);
	if (mid < r) res += query(u << 1 | 1, l, r);
	return res;
}

signed main() {
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n >> q;
	for (int i = 1; i <= n; ++i) cin >> a[i];
	build(1, 1, n);
	for (int i = 1, op, x, y, z; i <= q; ++i) {
		cin >> op >> x >> y;
		x++, y++;// aaa!
		if (op == 1) {
			cin >> z;
			add(1, x, y, z);
		} else if (op == 2) {
			cin >> z;
			chu(1, x, y, z);
		} else if (op == 3) cout << querymin(1, x, y) << '\n';
		else cout << query(1, x, y) << '\n';
	}
}
2024/3/26 13:57
加载中...