首页 > 其他分享 >hdu-5306(区间最值+线段树)

hdu-5306(区间最值+线段树)

时间:2023-04-05 17:34:33浏览次数:47  
标签:hdu LL tr 5306 se rc include mx 最值

hdu

Gorgeous Sequence

HDU - 5306

题意:

给定一个长度为n的区间,做m次操作,三种操作

  1. 对于序列[L,R]区间中的每个ai,用min(ai,x)替换。
  2. 打印序列[L,R]区间的最大值
  3. 打印序列[L,R]区间和

因为区间和与区间最值无关,所以无法直接用简单的标记处理。

区间最值与区间和如何扯上关系呢?我们通树状数组维护四个信息,分别是区间和sum,最大值mx,严格次大值se,最大值个数t

当我们用x来进行区间修改时:

(1) 当mx<=x时,这次修改不影响。

(2)当se<x < mx时,此时sum需要更新,sum = sum - t(mx- x), 以及mx = x //自己想想为什么

(3)当se>=x时,无法更新,我们递归他的左右结点

#define _CRT_SECURE_NO_WARNINGS 1
#include<algorithm>
#include<fstream>
#include<iostream>
#include<cstdio>
#include<deque>
#include<string>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<unordered_map>
using namespace std;
#define INF 0x3f3f3f3f
#define MAXN 310000
#define N 1000010
#define M 10007
#define endl '\n'
#define exp 1e-8
#define lc p << 1
#define rc p << 1|1
#define lowbit(x) ((x)&-(x))
const double pi = acos(-1.0);
typedef long long LL;
typedef unsigned long long ULL;
inline ULL read() {
	ULL x = 0, f = 1;
	char ch = getchar();
	while (ch < '0' || ch>'9') {
		if (ch == '-')
			f = -1;
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9') {
		x = (x << 1) + (x << 3) + (ch ^ 48);
		ch = getchar();
	}
	return x * f;
}
void print(ULL x) {
	if (x > 9)print(x / 10);
	putchar(x % 10 ^ 48);
}
struct tree
{
	LL l, r,sum,mx,se,num;  //sum区间和,mx最大值,se次大值,num最大值个数,不用在写标记的原因:mx可以充当标记的作用
}tr[N*4];
LL arr[N], t, n, m;
void pushup(int p)  //pushup()函数的改写
{
	tr[p].mx = max(tr[lc].mx, tr[rc].mx);
	tr[p].sum = tr[lc].sum + tr[rc].sum;
	if (tr[lc].mx == tr[rc].mx)   //当左节点和右结点最大值相同时
	{
		tr[p].se = max(tr[lc].se, tr[rc].se);  //次大值从左节点的次大值和右节点的次大值寻找最大
		tr[p].num = tr[lc].num + tr[rc].num;   //最大值相等,最大值个数自然是相加
	}
	else
	{
		tr[p].se = max(tr[lc].se, tr[rc].se);        
		tr[p].se = max(tr[p].se, min(tr[lc].mx, tr[rc].mx));   //为什么可以求得最大值,可以自己模拟一下
		tr[p].num = tr[lc].mx > tr[rc].mx ? tr[lc].num : tr[rc].num;  //取了谁的最大值,那么最大值个数也应该取谁的
	}
}
void addtag(int p, int k)   
{
	if (tr[p].mx <= k)return;
	tr[p].sum -= tr[p].num * (tr[p].mx - k);
	tr[p].mx = k;
}
void pushdown(LL p)
{
	addtag(lc, tr[p].mx);  //mx充当了标记的作用
	addtag(rc,tr[p].mx);
}
void build(LL p, LL l, LL r)
{                                                                                                                                                        
	tr[p] = { l,r,arr[l],arr[l],-1,1};
	if (l == r)return;
	LL m = l + r >> 1;
	build(lc, l, m);
	build(rc, m + 1, r);
	pushup(p);
}
void update(LL p, LL x, LL y, LL k)
{
	if (k >=tr[p].mx)return;  //第一种情况
	if (x <= tr[p].l && tr[p].r <= y) //第二种情况
	{
		if (k>tr[p].se)
		{
			addtag(p, k);
			return;
		}
	}
	pushdown(p);
	LL m = tr[p].l + tr[p].r >> 1;
	if (x <= m)update(lc, x, y, k);
	if (y > m)update(rc, x, y, k);
	pushup(p);
}
LL query1(LL p, LL x, LL y)  //求区间最大值
{
	if (x <= tr[p].l && tr[p].r <= y)
	{
		return tr[p].mx;
	}
	pushdown(p);
	LL ans = 0;
	LL m = tr[p].l + tr[p].r >> 1;
	if (x <= m)ans = max(ans,query1(lc, x, y));
	if (y > m)ans = max( ans,query1(rc, x, y));
	return ans;
}
LL query2(LL p, LL x, LL y)  //求区间和
{
	if (x <= tr[p].l && tr[p].r <= y)
	{
		return tr[p].sum;
	}
	pushdown(p);
	LL ans = 0;
	LL m = tr[p].l + tr[p].r >> 1;
	if (x <= m)ans += query2(lc, x, y);
	if (y > m)ans += query2(rc, x, y);
	return ans;
}
int main()
{
	t = read();
	while (t--)
	{
		n = read(), m = read();
		for (int i = 1; i <= n; i++)
		{
			arr[i] = read();
		}
		build(1, 1, n);
		while (m--)
		{
			LL a, x, y, k;
			a = read(), x = read(), y = read();
			if (a == 0)
			{
				k = read();
				update(1, x, y, k);
			}
			else if (a == 1)
			{
				printf("%lld\n", query1(1, x, y));
			}
			else
			{
				printf("%lld\n", query2(1, x, y));
			}
		}
	}
	return 0;
}

标签:hdu,LL,tr,5306,se,rc,include,mx,最值
From: https://www.cnblogs.com/wyh344866/p/17289936.html

相关文章

  • HDU 2196 Computer(树形DP) 入门模板
    ComputerTimeLimit:1000/1000MS(Java/Others)    MemoryLimit:32768/32768K(Java/Others)TotalSubmission(s):34313    AcceptedSubmission(s):5345 ProblemDescriptionAschoolboughtthefirstcomputersometimeago(sothiscomputer'sidis1).D......
  • HDU动态规划题解目录
    ProblemA:MaxSum(HDU1003)   点击这里ProblemB:CommonSubsequence(HDU1159)    点击这里ProblemC:SuperJumping!Jumping!Jumping!(HDU1087)    点击这里ProblemD:HumbleNumbers(HDU1058)   点击这里ProblemE:MonkeyandBanana(HDU1069)    点击这里ProblemF:......
  • hdu - 4578(线段树)
    题目:Yuanfangispuzzledwiththequestionbelow:Therearenintegers,a1,a2,…,an.Theinitialvaluesofthemare0.Therearefourkindsofoperations.Operation1:Addctoeachnumberbetweenaxandayinclusive.Inotherwords,dotransformationak&......
  • 十九道初中动点最值题(资料来自网上)
    ......
  • HDU 3328 Flipper 栈的应用
    FlipperTimeLimit:2000/1000MS(Java/Others)    MemoryLimit:32768/32768K(Java/Others)TotalSubmission(s):521    AcceptedSubmission(s):334ProblemDescriptionLittleBobbyRoberts(sonofBigBob,ofProblemG)playsthissolitairememory......
  • hdu3595 GG and MM Every SG博弈
    这是一道很神奇的题,神奇的地方在于全网这个模型只有这题什么是EverySG?不同于普通的ICG,它由多个游戏同时进行,且必须同时进行比如这道题,要求先手一次对所有石头堆都要操作显然对于单独的每种情况,我们都可以求出这是必败态还是必胜态现在摆在我们眼前的就有一堆游戏,对于每个游......
  • hdu3980 Paint Chain SG函数+SG定理+记忆化搜索
    liyishui今天学习博弈,因为liyishui今天写树链剖分写得有点理智--题意:有一个圆,上面有n个豆子,每次要挑出连续m个没染色的豆子进行染色,不能移动时输掉游戏问先手必胜还是后手必胜,其中n、m<=1000题解:会很朴素地想到如果第一个人拿走了m个,那么剩下的就是一条链的问题。所以可以先......
  • 2011年最值得拥有的五大联网设备
    还记得当年坐在笨重的计算机和CRT显示器前,通过拨号上网么?幸运的是,那些日子早已消逝在时间长河中,今天,我们可以通过各种或大或小的设备快速联网,无需再经过漫长的等待,也无需再......
  • 确定比赛名次 HDU - 1285 (拓扑排序)
    题意:有N个比赛队(1≤N≤500),编号依次为1,2,3,...,N进行比赛,比赛结束后,裁判委员会要将所有参赛队伍从前往后依次排名,但现在裁判委员会不能直接获得每个队的比赛成绩,只知道每场比......
  • Transformation HDU - 4578
    题目链接\(1\)题目链接\(2\)题解设一个区间的和、平方和、立方和分别是\(sum_0,sum_1,sum_2\)对于\(add\)操作,推推公式可知\(\begin{cases}newsum_2=sum_2+val^3......