【数据结构】之分块与莫队理解及基础题目推荐

分块

高级的暴力,把序列分成一块一块的,利用加懒标记的方式进行区间操作。而没有被分成块的就直接暴力修改,所以时间复杂度方面感觉很玄学。

例一

给一个长度为n的序列,每次给l,r和c,表示把区间l~r都加c,或者输出a[r]的值

一开始只知道原理而没见过板子的时候

void fenkuai()
{
   
   
	for(int i=1;i<=n;i+=m)kuaiz[++tot]=i;
	kuaiz[++tot]=kuaiz[tot-1]+m;
}//n为序列长度,m为块的大小

写下这种幼稚的板子,用 k u a i z [ t o t ] kuaiz[tot] kuaiz[tot] 记录每一块的左端点在序列中的下标。
然后

void xg(int x,int y,int z)
{
   
   
	int p=lower_bound(kuaiz,kuaiz+tot,x)-kuaiz;
	int q=upper_bound(kuaiz,kuaiz+tot,y)-kuaiz;
	for(int i=p+1;i<q;i++)lan[i]+=z;
	for(int i=x;i<kuaiz[p];i++)a[i]+=z;
	for(int i=kuaiz[q-1];i<=y;i++)a[i]+=z;
	return;
}

以这种错误的方式进行整块整块的懒标记,和非整块部分的直接修改,然后听取 W A WA WA 声一片。(当然不排除思路没错但写法有误。)然后在高强度自闭下看了别人的写法。
在这里插入图片描述
后来也确实有人的实现跟我一开始所想的差不多

void change(int ll,int rr,long long d)
{
   
   
	int p=pos[ll],q=pos[rr];
	if(p==q)
	{
   
   
		for(int i=ll;i<=rr;i++) a[i]+=d;
		sum[p]+=d*(rr-ll+1);
	}
	else
	{
   
   
		for(int i=p+1;i<q;i++) add[i]+=d;
		for(int i=ll;i<=r[p];i++) a[i]+=d;
		sum[p]+=d*(r[p]-ll+1);
		for(int i=l[q];i
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值