【loj6283】数列分块练习 7

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

#include
#include
#include
#include
#include
#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;
}

你可能感兴趣的:(LibreOJ,中级数据结构-分块)