注意到当一个数开方到1后就不再变了,每个数开方次数不会太多,所以进行更新时如果该区间的数字都是1了就直接return
#include <stdio.h>
#include <string.h>
#include <math.h>
#define maxn 100100
__int64 sum[4*maxn];
void build(int l,int r,int o)
{
if(l==r)
{
scanf("%I64d",&sum[o]);
return ;
}
int m=(l+r)/2;
build(l,m,o*2);
build(m+1,r,o*2+1);
sum[o]=sum[o*2]+sum[o*2+1];
}
void update(int ql,int qr,int l,int r,int o)
{
if(sum[o]==r-l+1) return ;
if(l==r)
{
sum[o]=(__int64)sqrt(1.0*sum[o]);
return ;
}
int m=(l+r)/2;
if(ql<=m) update(ql,qr,l,m,o*2);
if(qr>m) update(ql,qr,m+1,r,o*2+1);
sum[o]=sum[o*2]+sum[o*2+1];
}
__int64 query(int ql,int qr,int l,int r,int o)
{
if(ql<=l&&r<=qr)
return sum[o];
__int64 ans=0;
int m=(l+r)/2;
if(ql<=m) ans+=query(ql,qr,l,m,o*2);
if(qr>m) ans+=query(ql,qr,m+1,r,o*2+1);
return ans;
}
int main()
{
int n;
int T;
int x,y,z;
int num=0;
while(scanf("%d",&n)!=EOF)
{
num++;
build(1,n,1);
printf("Case #%d:\n",num);
scanf("%d",&T);
while(T--)
{
int temp;
scanf("%d%d%d",&x,&y,&z);
if(y>z) {temp=y;y=z;z=temp;}
if(x==0) update(y,z,1,n,1);
if(x==1) printf("%I64d\n",query(y,z,1,n,1));
}
puts("");
}
return 0;
}