【XSY2111】Chef and Churus 分块 树状数组

题目描述

  有一个长度为\(n\)的数组\(A\)\(n\)个区间\([l_i,r_i]\),有\(q\)次操作:

   \(1~x~y\):把\(a_x\)改成\(y\)

   \(2~x~y\):求第\(l\)个区间到第\(r\)个区间的区间和的和。

  \(n,q\leq {10}^5,a_i\leq {10}^9\)

题解

  分块。

  设\(s_i\)为第\(i\)块的所有区间的区间和,\(d_{i,j}\)为第\(i\)块有多少个区间包含了\(j\)这个位置。

  修改时修改树状数组和每个区间的区间和。设当前\(a_x=v\),则\(s_i+=(y-v)\times d_{i,x}\)

  查询时完整的区间直接查询区间和,不完整的区间就暴力查询。

  设块大小为\(m\),时间复杂度为

\[T(n)=O(\frac{n}{m}+m\log n) \]

  当\(m=\sqrt{\frac{n}{\log n}}\)

\[T(n)_{\min}=O(n\sqrt{n\log n}) \]

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<utility>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
ull c[100010];
int a[100010];
int n;
void add(int x,ull v)
{
	for(;x<=n;x+=x&-x)
		c[x]+=v;
}
ull sum(int x)
{
	ull s=0;
	for(;x;x-=x&-x)
		s+=c[x];
	return s;
}
int bl;
ull s[1010];
int d[1010][100010];
int l[100010];
int r[100010];
int block[100010];
int left[100010];
int right[100010];
int main()
{
	memset(c,0,sizeof c);
//	freopen("xsy2111.in","r",stdin);
//	freopen("xsy2111.out","w",stdout);
	int m;
	scanf("%d",&n);
	int i;
	for(i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
		add(i,a[i]);
	}
	bl=100;
	m=(n+bl-1)/bl;
	for(i=1;i<=n;i++)
		block[i]=(i+bl-1)/bl;
	for(i=1;i<=m;i++)
	{
		left[i]=(i-1)*bl+1;
		right[i]=min(i*bl,n);
	}
	for(i=1;i<=n;i++)
	{
		scanf("%d%d",&l[i],&r[i]);
		s[block[i]]+=sum(r[i])-sum(l[i]-1);
		d[block[i]][l[i]]++;
		if(r[i]<n)
			d[block[i]][r[i]+1]--;
	}
	int j;
	for(i=1;i<=m;i++)
		for(j=2;j<=n;j++)
			d[i][j]+=d[i][j-1];
	int q;
	scanf("%d",&q);
	int op,x,y,k;
	for(i=1;i<=q;i++)
	{
		scanf("%d%d%d",&op,&x,&y);
		if(op==1)
		{
			int v=a[x];
			for(j=1;j<=m;j++)
				s[j]+=ull(y-v)*d[j][x];
			add(x,y-v);
			a[x]=y;
		}
		else
		{
			ull ans=0;
			for(j=block[x];j<=block[y];j++)
				if(left[j]>=x&&right[j]<=y)
					ans+=s[j];
				else
				{
					int mi=max(left[j],x);
					int mx=min(right[j],y);
					for(k=mi;k<=mx;k++)
						ans+=sum(r[k])-sum(l[k]-1);
				}
			printf("%llu\n",ans);
		}
	}
	return 0;
}
posted @ 2018-03-05 20:59  ywwyww  阅读(235)  评论(0编辑  收藏  举报