一道很早之前就见过的题,一直没写过
暴力更新打标记就ok
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
ll A[N];
struct SegmenTree{
struct segmenttree{
int l,r;ll val;bool over;
#define l(x) Tree[x].l
#define r(x) Tree[x].r
#define val(x) Tree[x].val
#define over(x) Tree[x].over
}Tree[N*4];
void update(int p){
over(p)=over(p*2)&&over(p*2+1);
val(p)=val(p*2)+val(p*2+1);
}
void build(int p,int l,int r){
l(p)=l;r(p)=r;
if(l==r){
val(p)=A[l];
if(A[l]<=1)over(p)=1;
return;
}
int mid=(l+r)/2;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
update(p);
}
ll ask(int p,int l,int r){
if(l<=l(p)&&r>=r(p))return val(p);
int mid=(l(p)+r(p))/2;
ll ans=0;
if(l<=mid)ans+=ask(p*2,l,r);
if(r>mid)ans+=ask(p*2+1,l,r);
return ans;
}
void change(int p,int l,int r){
if(l(p)==r(p)){
val(p)=sqrt(val(p));
if(val(p)<=1)over(p)=1;
return;
}
if(l<=l(p)&&r>=r(p)){
if(!over(p*2))change(p*2,l,r);
if(!over(p*2+1))change(p*2+1,l,r);
update(p);
return;
}
int mid=(l(p)+r(p))/2;
if(l<=mid&&!over(p*2))change(p*2,l,r);
if(r>mid&&!over(p*2+1))change(p*2+1,l,r);
update(p);
}
}T;
int main(){
int n,m,op,x,y;cin>>n;
for(int i=1;i<=n;++i)scanf("%lld",&A[i]);
T.build(1,1,n);
cin>>m;
while(m--){
scanf("%d%d%d",&op,&x,&y);
if(op==1)printf("%lld\n",T.ask(1,x,y));
else T.change(1,x,y);
}
}