一个数最多是会被开方次数不会很多,所以直接暴力修改即可.
#include <bits/stdc++.h>
#define N 100005
#define ll long long
#define lson now<<1
#define rson now<<1|1
#define setIO(s) freopen(s".in","r",stdin) , freopen(s".out","w",stdout)
using namespace std;
int n,m,tag[N<<2];
ll A[N],sum[N<<2];
void build(int l,int r,int now)
{
if(l==r)
{
sum[now]=A[l];
if(sum[now]==1ll) tag[now]=1;
return;
}
int mid=(l+r)>>1;
if(l<=mid) build(l,mid,lson);
if(r>mid) build(mid+1,r,rson);
sum[now]=sum[lson]+sum[rson];
if(sum[now]==r-l+1) tag[now]=1;
}
ll query(int l,int r,int now,int L,int R)
{
if(l>=L&&r<=R) return sum[now];
int mid=(l+r)>>1;
ll re=0;
if(L<=mid) re+=query(l,mid,lson,L,R);
if(R>mid) re+=query(mid+1,r,rson,L,R);
return re;
}
void update(int l,int r,int now,int L,int R)
{
if(tag[now]) return ;
if(l==r)
{
sum[now]=(ll)sqrt(sum[now]);
return;
}
int mid=(l+r)>>1;
if(L<=mid) update(l,mid,lson,L,R);
if(R>mid) update(mid+1,r,rson,L,R);
sum[now]=sum[lson]+sum[rson];
if(sum[now]==r-l+1) tag[now]=1;
}
int main()
{
int i,j;
// setIO("input");
scanf("%d",&n);
for(i=1;i<=n;++i) scanf("%lld",&A[i]);
build(1,n,1);
scanf("%d",&m);
for(i=1;i<=m;++i)
{
int op,l,r;
scanf("%d%d%d",&op,&l,&r);
if(l>r) swap(l,r);
if(op==1)
{
printf("%lld\n",query(1,n,1,l,r));
}
else
{
update(1,n,1,l,r);
}
}
return 0;
}