CDOJ 1324 卿学姐与公主 (分块入门)

题目链接

分块:实际上是暴力算法,是优雅的暴力,把区间分成根号n块,保存每个元素所在块,以及块的左右端点,下面是一道模板题,模板来自B站卿学姐。首先是用到的信息。

  • b e l o n g [ m a x n ] belong[maxn] belong[maxn] —— 代表每个元素所在的块。
  • l [ m a x n ] , r [ m a x n ] l[maxn],r[maxn] l[maxn],r[maxn] —— 代表每一块的左右边界。
  • n u m , b l o c k num,block num,block —— 代表块的数目,块的大小。
    注意的点有:在查询的时候要考虑两个端点是否在同一个分块内、初始化的时候,要考虑最后一个分块的右端点是否超出n。

题目:当点修改+查询区间最大值。

#include <bits/stdc++.h>
#define ll long long
using namespace std;

const int maxn = 1e5+7;

int belong[maxn],num,l[maxn],r[maxn],block,n,q;
ll Max[maxn],a[maxn];

void build()
{
	block = sqrt(n);
	num = n/block;
	if(n%block)num++;    
	for(int i=1;i<=num;i++)
	l[i] = (i-1)*block+1,r[i] = i*block;
	r[num] = n;
	for(int i=1;i<=n;i++)belong[i] = (i-1)/block+1; //计算i属于哪一块 
	
	for(int i=1;i<=num;i++)   //更新块内答案 
		for(int j=l[i];j<=r[i];j++)
			Max[i] = max(a[j],Max[i]);
}

void up(int x,int y)
{
	a[x] += y;
	Max[belong[x]] = max(a[x],Max[belong[x]]);
}

long long qu(int x,int y)
{
	ll ans = 0;
	if(belong[x] == belong[y])  //特判是否在同一块 
	{
		for(int i=x;i<=y;i++)ans=max(ans,a[i]);
		return ans;
	}
	for(int i=x;i<=r[belong[x]];i++)ans = max(a[i],ans);
	for(int i=belong[x]+1;i<belong[y];i++)ans = max(ans,Max[i]);
	for(int i=l[belong[y]];i<=y;i++)ans = max(ans,a[i]);
	return ans;
}
int main()
{
	scanf("%d%d",&n,&q);
	while(q--)
	{
		int op,x,y;
		scanf("%d%d%d",&op,&x,&y);
		if(op == 1)up(x,y);
		else printf("%lld\n",qu(x,y));
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值