树状数组维护前缀和
并查集维护从一个点向后(包括这个点)第一个权值>1的点
因为权值<=1更新是没有必要的
而开根号一个int的数顶多开5次就成了1
复杂度是nlogn的
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<iostream>
#include<algorithm>
#define lowbit(x) x&(-x)
#define T 100010
using namespace std;
int sc()
{
int i=0,f=1;char c=getchar();
while(c>'9'||c<'0'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9')i=i*10+c-'0',c=getchar();
return i*f;
}
long long tr[T];
int nxt[T],a[T];
int n,m;
int find(int x){return nxt[x]==x?x:nxt[x]=find(nxt[x]);}
void change(int x,int f){ for(;x<=n;x+=lowbit(x))tr[x]+=f; }
void solve(int l,int r)
{
for(int i=find(nxt[l]);i<=r;i=find(nxt[i+1]))
{
int x=(int)sqrt(a[i]);
change(i,x-a[i]);
a[i]=x;
if(a[i]<=1)nxt[i]=find(nxt[i+1]);
}
}
long long ask(int x)
{
long long ans=0;
for(;x;x-=lowbit(x)) ans+=tr[x];
return ans;
}
int main()
{
n=sc();
for(int i=1;i<=n;i++)a[i]=sc(),change(i,a[i]);
for(int i=1;i<=n;i++)nxt[i]=i;nxt[n+1]=n+1;
m=sc();
for(int i=1;i<=m;i++)
{
int x=sc(),a=sc(),b=sc();
if(x==2) solve(a,b);
else printf("%lld\n",ask(b)-ask(a-1));
}
return 0;
}