为什么这份区间开方区间查询的代码跑的这么慢(n=50000时3s)。思路是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 ;
}