分块模板

#include<bits/stdc++.h>//分块模板新 http://poj.org/problem?id=3468
#define maxn 100010
using namespace std;
inline int read()
{
	int x=0;
	char c;
	while(!isdigit(c))
		c=getchar();
	while(isdigit(c))
	{
		x=(x<<3)+(x<<1)+(c-48);
		c=getchar();
	}
	return x;
}
int origin[maxn];
int gro[maxn];
int head[maxn];
int end[maxn];
int add[maxn];
int sum[maxn];
#define gx gro[x]
#define gy gro[y]
void query()
{
	int x;
	int y;
	x=read();
	y=read();
	int sumx=0;
	int sumy=0;
	int sumtot=0;
	if(gx!=gy)
	{
		if(x!=head[gx])
			for(int i=x;i<=end[gx];i++)
				sumx+=origin[i]+add[gx];
		else
			sumx=sum[gx]+(end[gx]-head[gx]+1)*add[gx];
		if(y!=end[gy])
			for(int i=head[gx];i<=y;i++)
				sumy+=origin[i]+add[gy];
		else
			sumy=sum[gy]+(end[gy]-head[gy]+1)*add[gy];
		for(int i=gx+1;i<=gy-1;i++)
			sumtot+=sum[i]+(end[i]-head[i]+1)*add[i];
	}
	else
	{
		for(int i=x;i<=y;i++)
		{
			sumtot+=origin[i]+add[gx];
		}
	}
	cout<<sumx+sumtot+sumy<<endl;
}
void change()
{
	int x;
	int y;
	int num;
	x=read();
	y=read();
	num=read();
	if(gx!=gy)
	{
		if(x!=head[gx])
		{
			for(int i=x;i<=end[gx];i++)
				origin[i]+=num;
			sum[gx]+=(end[gx]-x+1)*num;
		}
		else
			add[gx]+=num;
			
			if(y!=end[gy])
		{
			for(int i=head[gy];i<=y;i++)
				origin[i]+=num;
			sum[gy]+=(y-head[gy]+1)*num;
		}
		else
			add[gy]+=num;
			
		for(int i=gx+1;i<=gy-1;i++)
				add[i]+=num;
	}
	else
	{
		for(int i=x;i<=y;i++)
			origin[i]+=num;
		sum[gx]+=(y-x+1)*num; 
	}
}
int main()
{
	int n;
	n=read();
	for(int i=1;i<=n;i++)
		origin[i]=read();
	int len=(int)sqrt(n);
	int tot=len;
	for(int i=1;i<=tot;i++)
	{
		head[i]=(i-1)*len+1;
		end[i]=i*len;		
	} 
	if(end[tot]!=n)
	{
		tot++;
		head[tot]=end[tot-1]+1;
		end[tot]=n;
	}
	for(int i=1;i<=tot;i++)
		for(int j=head[i];j<=end[i];j++)
		{
			gro[j]=i;
			sum[i]+=origin[j];
		}
	int m;
	m=read();
	for(int i=1;i<=m;i++)
	{
		char c;
		c=read();
		if(c=='Q')
			query();
		if(c=='C')
			change();
	}
	return 0;
}

本人分块模板,区间修改+区间求和 时间复杂度大约O(m*3*log_2*n))

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值