HDU - 5306 Gorgeous Sequence

题意:

给定一个长为 n 的数组 a,有 m 个操作,①:0,x,y,t,令 a i = m i n ( a i , t ) , i [ x , y ] a_i = min(a_i, t),i∈[x, y] ;②:1,x,y,询问 max{ a x , a x + 1 , . . . , a y a_x, a_{x+1}, ..., a_y };③:2,x,y,询问 i = x y a i \sum_{i=x}^{y}a_i 。(n, m <= 1e6)

链接:

https://vjudge.net/problem/HDU-5306

解题思路:

维护区间最大值、最大值个数、严格次大值及区间和,则对于一个取小操作,分三类:① t >= 最大值,直接返回;② 次大值 < t < 最大值,打上懒惰标记,更新最大值即可;③ t <= 次大值,递归更新。总复杂度可证为 O(mlogn),详见16年国家集训队论文集。

参考代码:

#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
#define pb push_back
#define sz(a) ((int)a.size())
#define mem(a, b) memset(a, b, sizeof a)
#define lson (rt << 1)
#define rson (rt << 1 | 1)
#define gmid (l + r >> 1)
const int maxn = 1e6 + 5;
const int maxm = 2e6 + 5;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;

ll mx[maxn << 2], mx2[maxn << 2];
ll sum[maxn << 2], cov[maxn << 2];
int a[maxn], num[maxn << 2];
int n, m;

void pushUp(int rt){

	sum[rt] = sum[lson] + sum[rson];
	if(mx[lson] == mx[rson]){

		mx[rt] = mx[lson], num[rt] = num[lson] + num[rson];
		mx2[rt] = max(mx2[lson], mx2[rson]);
	}
	else if(mx[lson] > mx[rson]){

		mx[rt] = mx[lson], num[rt] = num[lson];
		mx2[rt] = max(mx2[lson], mx[rson]);
	}
	else{

		mx[rt] = mx[rson], num[rt] = num[rson];
		mx2[rt] = max(mx[lson], mx2[rson]);
	}
}

void build(int l, int r, int rt){

	cov[rt] = -1;
	if(l == r){

		mx[rt] = a[l], mx2[rt] = -1;
		sum[rt] = a[l], num[rt] = 1;
		return;
	}
	int mid = gmid;
	build(l, mid, lson);
	build(mid + 1, r, rson);
	pushUp(rt);
}

void pushDown2(int rt, int son){

	if(cov[rt] >= mx[son]) return;
	sum[son] -= num[son] * (mx[son] - cov[rt]);
	mx[son] = cov[son] = cov[rt];
}

void pushDown(int rt){

	if(cov[rt] != -1){

		pushDown2(rt, lson);
		pushDown2(rt, rson);
		cov[rt] = -1;
	}
}

void dfs(int l, int r, int rt, ll val){

	if(val >= mx[rt]) return;
	if(val > mx2[rt]){

		cov[0] = val;
		pushDown2(0, rt);
		return;
	}
	int mid = gmid;
	pushDown(rt);
	dfs(l, mid, lson, val);
	dfs(mid + 1, r, rson, val);
	pushUp(rt);
}

void update(int l, int r, int rt, int L, int R, ll val){

	if(val >= mx[rt]) return;
	if(l >= L && r <= R){

		if(val > mx2[rt]){

			cov[0] = val;
			pushDown2(0, rt);
			return;
		}
		return dfs(l, r, rt, val);
	}
	int mid = gmid;
	pushDown(rt);
	if(L <= mid) update(l, mid, lson, L, R, val);
	if(R > mid) update(mid + 1, r, rson, L, R, val);
	pushUp(rt);
}

ll queryM(int l, int r, int rt, int L, int R){

	if(l >= L && r <= R) return mx[rt];
	int mid = gmid; ll ret = -1;
	pushDown(rt);
	if(L <= mid) ret = max(ret, queryM(l, mid, lson, L, R));
	if(R > mid) ret = max(ret, queryM(mid + 1, r, rson, L, R));
	return ret;
}

ll queryS(int l, int r, int rt, int L, int R){

	if(l >= L && r <= R) return sum[rt];
	int mid = gmid; ll ret = 0;
	pushDown(rt);
	if(L <= mid) ret += queryS(l, mid, lson, L, R);
	if(R > mid) ret += queryS(mid + 1, r, rson, L, R);
	return ret;
}

int main(){

//	ios::sync_with_stdio(0); cin.tie(0);
	int t; scanf("%d", &t);
	while(t--){

		scanf("%d%d", &n, &m);
		for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);
		build(1, n, 1);
		while(m--){

			int opt, x, y, z; scanf("%d%d%d", &opt, &x, &y);
			if(opt == 0){

				scanf("%d", &z);
				update(1, n, 1, x, y, z);
			}
			else if(opt == 1){

				ll ret = queryM(1, n, 1, x, y);
				printf("%lld\n", ret);
			}
			else{

				ll ret = queryS(1, n, 1, x, y);
				printf("%lld\n", ret);
			}
		}
	}
	return 0;
}
发布了55 篇原创文章 · 获赞 0 · 访问量 1275

猜你喜欢

转载自blog.csdn.net/weixin_44059127/article/details/101221842