关于分块区间开方
  • 板块灌水区
  • 楼主king_xbz
  • 当前回复9
  • 已保存回复9
  • 发布时间2020/10/8 15:28
  • 上次更新2023/11/5 11:33:47
查看原帖
关于分块区间开方
244059
king_xbz楼主2020/10/8 15:28

为什么这份区间开方区间查询的代码跑的这么慢(n=50000时3s)。思路是n\sqrt n一块,当一个块所有值都是0或者1后就不修改,否则暴力修改。

求dalao看看如何能优化一下(时限500ms),蟹蟹了!!!

signed main()
{
	ios::sync_with_stdio(false);
	n=read();
	for(fint i=1;i<=n;i++)
	a[i]=read();
	for(fint i=1;i<=n;i++)
	{
		int op,l,r,c;
		op=read(),l=read(),r=read(),c=read();
		if(op==0)
		sqrts(l,r);
		else
		cout<<query(l,r)<<endl;
	}
	return 0;
} 

inline void pre()
{
	block.siz=sqrt(n);
	block.tot=n/block.siz;
	if(n%block.siz)
	block.tot++;
	build(1,block.siz,1);
	for(fint i=1;i<=n;i++)
	bel[i]=(i-1)/block.siz+1,tt[bel[i]]+=a[i];
	return ;
}

inline void build(int l,int r,int now)
{
	if(now==n)
	{
		L[now]=l,R[now]=n;
		return ;
	}
	L[now]=l,R[now]=r;
	build(r+1,r+block.siz,now+1);
	return ;
}

inline void sqrts(int l,int r)
{
	if(bel[l]==bel[r])
	{
		for(fint i=l;i<=r;i++)
		{
			int chan=sqrt(a[i]);
			tt[bel[l]]-=(a[i]-chan);
			a[i]=chan;
		}
		return ;
	}
	for(fint i=l;i<=R[bel[l]];i++)
	{
		int chan=sqrt(a[i]);
		tt[bel[l]]-=(a[i]-chan);
		a[i]=chan;
	}
	for(fint i=L[bel[r]];i<=r;i++)
	{
		int chan=sqrt(a[i]);
		tt[bel[r]]-=(a[i]-chan);
		a[i]=chan;
	}
	for(fint i=bel[l]+1;i<=bel[r]-1;i++)
	if(!lazy[i])
	change(i);
	return ;
}

inline int query(int l,int r)
{
	int ans=0;
	if(bel[l]==bel[r])
	{
		for(fint i=l;i<=r;i++)
		ans+=a[i];
		return ans;
	}
	for(fint i=l;i<=R[bel[l]];i++)
	ans+=a[i];
	for(fint i=L[bel[l]];i<=r;i++)
	ans+=a[i];
	for(fint i=bel[l]+1;i<=bel[r]-1;i++)
	ans+=tt[i];
	return ans;
}

inline void change(int x)
{
	for(fint i=L[x];i<=R[x];i++)
	{
		int chan=sqrt(a[i]);
		tt[x]-=(a[i]-chan);
		a[i]=chan;
	}
	for(fint i=L[x];i<=R[x];i++)
	if(a[i]!=0&&a[i]!=1)
	return ;
	lazy[x]=1;
	return ;
}
2020/10/8 15:28
加载中...