【loj6283】数列分块练习 7

本文介绍了一种处理大规模数列更新与查询操作的有效方法——数列分块算法。通过将数列分为多个块,并对每个块进行预处理,可以在较短时间内完成对数列的批量更新和单点查询。代码示例展示了如何实现分块、更新操作以及查询操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

「分块」数列分块入门1 – 9 by hzwer

#include<iostream>
#include<queue>
#include<cstdio>
#include<cmath>
#include<cstring>
#define inf 0x7f7f7f7f
#define N 100009
#define mod 10007
#define ll long long
using namespace std;

ll atag[N],mtag[N],v[N];
int blo[N],L[N],R[N];
int len,n;


ll read()
{
	char ch=getchar();ll f=1,ret=0;
	while(ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){ret=ret*10+ch-'0';ch=getchar();}
	return f*ret;
}

void reset(int x)
{
	for (int i=(x-1)*len+1;i<=min(x*len,n);i++)
		v[i]=(v[i]*mtag[x]+atag[x])%mod;
	mtag[x]=1;atag[x]=0;
}

void change(int opt,int l,int r,int d)
{
	int p=blo[l],q=blo[r];
	reset(p);
	for (int i=l;i<=min(R[l],r);i++)
	{
		if (opt==1) v[i]*=d;
		else v[i]+=d;v[i]%=mod;
	}
	if (p!=q)
	{
		reset(q);
		for (int i=L[r];i<=r;i++) 
		{
			if (opt==1) v[i]*=d;
			else v[i]+=d;v[i]%=mod;
		}
	}
	for (int i=p+1;i<=q-1;i++)
	{
		if (opt==1)
		{
			atag[i]=(atag[i]*d)%mod;
			mtag[i]=(mtag[i]*d)%mod;
		}
		else atag[i]=(atag[i]+d)%mod;
	}

}

int main()
{
	n=read();len=sqrt(n);

	for (int i=1;i<=n;i++) v[i]=read();
	for (int i=1;i<=n;i++){blo[i]=(i-1)/len+1;L[i]=(blo[i]-1)*len+1;R[i]=min(blo[i]*len,n);}
	for (int i=1;i<=blo[n];i++) mtag[i]=1;		
	for (int i=1;i<=n;i++)
	{
		int opt=read(),l=read(),r=read();ll d=read();
		if (opt==2) printf("%lld\n",(v[r]*mtag[blo[r]]+atag[blo[r]])%mod);
		else change(opt,l,r,d);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值