求调
查看原帖
求调
555381
zlttcl楼主2024/7/21 22:11

RT,参考了第二篇题解。

好像不修改前的询问都是对的,估计是修改锅了()

//#pragma GCC optimize(3,"Ofast","inline")
#include <bits/stdc++.h>
using namespace std;
#define int long long
typedef long long ll;
const int N = 5e5 + 10, inf = 2e9 + 1207;
int n, m, a[N];
inline ll read(){
	ll x = 0, m = 1;
	char ch = getchar();
	while(!isdigit(ch)){
		if(ch == '-') m = -1;
		ch = getchar();
	}
	while(isdigit(ch)){
		x = (x << 1) + (x << 3) + (ch ^ 48);
		ch = getchar();
	}
	return x * m;
}
inline void write(ll x){
	if(x < 0){
		putchar('-');
		write(-x);
		return;
	}
	if(x >= 10) write(x / 10);
	putchar(x % 10 + '0');
}
struct Tree{
	int l, r, sum, cnt;
	int max, all_max, se;
	int add1, add1_, add2, add2_;
}tree[N << 2];
inline void update(int k1, int k1_, int k2, int k2_, int sum){
	tree[sum].sum += (k1 * tree[sum].cnt + k2 * (tree[sum].r - tree[sum].l + 1 - tree[sum].cnt));
	tree[sum].all_max = max(tree[sum].all_max, tree[sum].max + k1_);
	tree[sum].add1 = max(tree[sum].add1_, tree[sum].add1 + k1_);
	tree[sum].max += k1, tree[sum].add1 += k1;
	tree[sum].add2_ = max(tree[sum].add2_, tree[sum].add2 + k2_);
	if(tree[sum].se != -inf) tree[sum].se += k2;
	tree[sum].add2 += k2;
}
inline void pushup(int sum){
	tree[sum].sum = tree[sum << 1].sum + tree[sum << 1 | 1].sum;
	tree[sum].all_max = max(tree[sum << 1].all_max, tree[sum << 1 | 1].all_max);
	if(tree[sum << 1].max = tree[sum << 1 | 1].max){
		tree[sum].max = tree[sum << 1].max;
		tree[sum].se = max(tree[sum << 1].se, tree[sum << 1 | 1].se);
		tree[sum].cnt = tree[sum << 1].cnt + tree[sum << 1 | 1].cnt;
	}else if(tree[sum << 1].max > tree[sum << 1 | 1].max){
		tree[sum].max = tree[sum << 1].max;
		tree[sum].se = max(tree[sum << 1].se, tree[sum << 1 | 1].max);
		tree[sum].cnt = tree[sum << 1].cnt;
	}else{
		tree[sum].max = tree[sum << 1 | 1].max;
		tree[sum].se = max(tree[sum << 1].max, tree[sum << 1 | 1].se);
		tree[sum].cnt = tree[sum << 1 | 1].cnt;
	}
}
inline void pushdown(int sum){
	int now = max(tree[sum << 1].max, tree[sum << 1 | 1].max);
	if(tree[sum << 1].max == now){
		update(tree[sum].add1, tree[sum].add1_, tree[sum].add2, tree[sum].add2_, sum << 1);
	}else update(tree[sum].add2, tree[sum].add2_, tree[sum].add2, tree[sum].add2_, sum << 1);
	if(tree[sum << 1 | 1].max == now){
		update(tree[sum].add1, tree[sum].add1_, tree[sum].add2, tree[sum].add2_, sum << 1 | 1);
	}else update(tree[sum].add2, tree[sum].add2_, tree[sum].add2, tree[sum].add2_, sum << 1 | 1);
	tree[sum].add1 = tree[sum].add1_ = tree[sum].add2 = tree[sum].add2_ = 0;
}
inline void build(int l, int r, int sum){
	tree[sum].l = l, tree[sum].r = r;
	tree[sum].add1 = tree[sum].add1_ = tree[sum].add2 = tree[sum].add2_ = 0;
 	if(l == r){
 		tree[sum].sum = tree[sum].max = tree[sum].all_max = a[l];
 		tree[sum].se = -inf, tree[sum].cnt = 1;
 		return;
	}
	int mid = (l + r) >> 1;
	build(l, mid, sum << 1);
	build(mid + 1, r, sum << 1 | 1);
	pushup(sum);
}
inline void add(int l, int r, int sum, int k){
	if(tree[sum].l > r || tree[sum].r < l) return;
	if(l <= tree[sum].l && tree[sum].r <= r){
		update(k, k, k, k, sum);
		return;
	}
	pushdown(sum);
	add(l, r, sum << 1, k);
	add(l, r, sum << 1 | 1, k);
	pushup(sum);
}
inline void modify(int l, int r, int sum, int k){
	if(tree[sum].l > r || tree[sum].r < l || k >= tree[sum].max) return;
	if(l <= tree[sum].l && tree[sum].r <= r && k > tree[sum].se){
		update(k - tree[sum].max, k - tree[sum].max, 0, 0, sum);
		return;
	}
	pushdown(sum);
	modify(l, r, sum << 1, k);
	modify(l, r, sum << 1 | 1, k);
	pushup(sum);
}
inline ll sigma(int l, int r, int sum){
	if(tree[sum].l > r || tree[sum].r < l) return 0;
	if(l <= tree[sum].l && tree[sum].r <= r) return tree[sum].sum;
	pushdown(sum);
	return sigma(l, r, sum << 1) + sigma(l, r, sum << 1 | 1);
}
inline ll query_max(int l, int r, int sum){
	if(tree[sum].l > r || tree[sum].r < l) return -inf;
	if(l <= tree[sum].l && tree[sum].r <= r) return tree[sum].max;
	pushdown(sum);
	return max(query_max(l, r, sum << 1), query_max(l, r, sum << 1 | 1));
}
inline ll query_all_max(int l, int r, int sum){
	if(tree[sum].l > r || tree[sum].r < l) return -inf;
	if(l <= tree[sum].l && tree[sum].r <= r) return tree[sum].all_max;
	pushdown(sum);
	return max(query_all_max(l, r, sum << 1), query_all_max(l, r, sum << 1 | 1));
}
signed main(){
	//freopen(".in", "r", stdin);
	//freopen(".out", "w", stdout);
    n = read(), m = read();
    for(int i = 1; i <= n; ++ i) a[i] = read();
	build(1, n, 1);
	while(m --){
		int op = read();
		if(op == 1){
			int l = read(), r = read(), k = read();
			add(l, r, 1, k);
		}else if(op == 2){
			int l = read(), r = read(), k = read();
			modify(1, r, 1, k);
		}else if(op == 3){
			int l = read(), r = read();
			write(sigma(l, r, 1)), putchar('\n');
		}else if(op == 4){
			int l = read(), r = read();
			write(query_max(l, r, 1)), putchar('\n');
		}else if(op == 5){
			int l = read(), r = read();
			write(query_all_max(l, r, 1)), putchar('\n');
		}
	} 
	return 0;
}

2024/7/21 22:11
加载中...