UOJ#288:基础数据结构练习题

题面

UOJ

Sol

玄学,不会势能分析
所以
维护区间最大最小值
把开根变成区间减法
如果最大值开根后的变化量和最小值的相等,就直接打个减法(lazy)

# include <bits/stdc++.h>
# define RG register
# define IL inline
# define Fill(a, b) memset(a, b, sizeof(a))
# define File(a) freopen(a".in", "r", stdin), freopen(a".out", "w", stdout)
using namespace std;
typedef long long ll;
const int _(1e5 + 5);

IL int Input(){
	RG int x = 0, z = 1; RG char c = getchar();
	for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
	for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
	return x * z;
}

int n, m;
struct Segment{
	ll mx, mn, tag, sum;
} T[_ << 2];

IL void Build(RG int x, RG int l, RG int r){
	if(l == r){
		T[x].mn = T[x].mx = T[x].sum = Input();
		return;
	}
	RG int mid = (l + r) >> 1, ls = x << 1, rs = x << 1 | 1;
	Build(ls, l, mid), Build(rs, mid + 1, r);
	T[x].mn = min(T[ls].mn, T[rs].mn);
	T[x].mx = max(T[ls].mx, T[rs].mx);
	T[x].sum = T[ls].sum + T[rs].sum;
}

IL void Adjust(RG int x, RG ll v, RG int l, RG int r){
	T[x].tag += v, T[x].mx += v, T[x].mn += v, T[x].sum += 1LL * (r - l + 1) * v;
}

IL void Pushdown(RG int x, RG int l, RG int mid, RG int r){
	if(T[x].tag == 0) return;
	Adjust(x << 1, T[x].tag, l, mid);
	Adjust(x << 1 | 1, T[x].tag, mid + 1, r);
	T[x].tag = 0;
}

IL void Modify2(RG int x, RG int l, RG int r, RG int L, RG int R, RG ll v){
	if(L <= l && R >= r){
		Adjust(x, v, l, r);
		return;
	}
	RG int mid = (l + r) >> 1, ls = x << 1, rs = x << 1 | 1;
	Pushdown(x, l, mid, r);
	if(L <= mid) Modify2(ls, l, mid, L, R, v);
	if(R > mid) Modify2(rs, mid + 1, r, L, R, v);
	T[x].mn = min(T[ls].mn, T[rs].mn);
	T[x].mx = max(T[ls].mx, T[rs].mx);
	T[x].sum = T[ls].sum + T[rs].sum;
}

IL void Modify1(RG int x, RG int l, RG int r, RG int L, RG int R){
	RG ll v1 = sqrt(T[x].mn), v2 = sqrt(T[x].mx);
	v1 -= T[x].mn, v2 -= T[x].mx;
	if(v1 == v2){
		Modify2(x, l, r, L, R, v1);
		return;
	}
	RG int mid = (l + r) >> 1, ls = x << 1, rs = x << 1 | 1;
	Pushdown(x, l, mid, r);
	if(L <= mid) Modify1(ls, l, mid, L, R);
	if(R > mid) Modify1(rs, mid + 1, r, L, R);
	T[x].mn = min(T[ls].mn, T[rs].mn);
	T[x].mx = max(T[ls].mx, T[rs].mx);
	T[x].sum = T[ls].sum + T[rs].sum;
}

IL ll Query(RG int x, RG int l, RG int r, RG int L, RG int R){
	if(L <= l && R >= r) return T[x].sum;
	RG int mid = (l + r) >> 1, ls = x << 1, rs = x << 1 | 1;
	RG ll ans = 0;
	Pushdown(x, l, mid, r);
	if(L <= mid) ans = Query(ls, l, mid, L, R);
	if(R > mid) ans += Query(rs, mid + 1, r, L, R);
	T[x].mn = min(T[ls].mn, T[rs].mn);
	T[x].mx = max(T[ls].mx, T[rs].mx);
	T[x].sum = T[ls].sum + T[rs].sum;
	return ans;
}

int main(RG int argc, RG char *argv[]){
	n = Input(), m = Input(), Build(1, 1, n);
	while(m--){
		RG int op = Input(), l = Input(), r = Input(), v;
		if(op == 1) v = Input(), Modify2(1, 1, n, l, r, v);
		else if(op == 2) Modify1(1, 1, n, l, r);
		else printf("%lld
", Query(1, 1, n, l, r));
	}
	return 0;
}

原文地址:https://www.cnblogs.com/cjoieryl/p/8582848.html