😣 😣 😣
T^T
重点:数据范围在2^63范围,最多开6次根号就会变成1,再开根号就没有意义,也就是说就算我们每次都更新到叶子结点,每个结点最多访问6次,直接更新就好;
#define ls p<<1
#define rs p<<1|1
#define lt p<<1,l,mid
#define rt p<<1|1,mid+1,r
ll sum[MX<<2];
void pushup(int p){sum[p]=sum[ls]+sum[rs];}
void build(int p,int l,int r)
{
if(l==r)
{
scanf("%lld",&sum[p]);
return;
}
int mid=(l+r)>>1;
build(lt);build(rt);
pushup(p);
}
void update(int p,int l,int r,int ql,int qr)
{
if(l==r)
{
sum[p]=sqrt(sum[p]);
return;
}
if(sum[p]<=r-l+1) return;
int mid=(l+r)>>1;
if(ql<=mid) update(lt,ql,qr);
if(qr>mid) update(rt,ql,qr);
pushup(p);
}
ll ans;
void que(int p,int l,int r,int ql,int qr)
{
if(l>=ql&&r<=qr)
{
ans+=sum[p];
return;
}
int mid=(l+r)>>1;
if(ql<=mid) que(lt,ql,qr);
if(qr>mid) que(rt,ql,qr);
}
signed main()
{
int n;
int _=0;
while(scanf("%d", &n) != EOF)
{
printf("Case #%d:\n",++_);
build(1,1,n);
int m;rd(m);
while(m--)
{
int op,l,r;
scanf("%d %d %d",&op,&l,&r);
if(l>r) swap(l,r);
if(op==0) update(1,1,n,l,r);
else
{
ans=0;
que(1,1,n,l,r);
printf("%lld\n",ans);
}
}
printf("\n");
}
return 0;
}