当你40分的时候,可以判断一个区间内的最大值是否>1,然后就可以AC了,具体的AC代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,a[100010],m,k,l,r,sum[400010],maxs[400010];
void build(int l,int r,int rt){
if(l==r){
scanf("%lld",&sum[rt]);
maxs[rt]=sum[rt];
return;
}
int mid=(l+r)>>1;
build(l,mid,rt<<1);
build(mid+1,r,rt<<1|1);
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
maxs[rt]=max(maxs[rt<<1],maxs[rt<<1|1]);
}
void update(int l,int r,int rt,int a,int b){
if(l==r){
sum[rt]=sqrt(sum[rt]);
maxs[rt]=sum[rt];
return;
}
int mid=(l+r)>>1;
if(maxs[rt<<1]>1&&a<=mid) update(l,mid,rt<<1,a,b);
if(maxs[rt<<1|1]>1&&b>mid) update(mid+1,r,rt<<1|1,a,b);
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
maxs[rt]=max(maxs[rt<<1],maxs[rt<<1|1]);
return;
}
int query(int l,int r,int rt,int a,int b){
if(a<=l&&b>=r) return sum[rt];
int mid=(l+r)>>1,ans=0;
if(a<=mid) ans+=query(l,mid,rt<<1,a,b);
if(b>mid) ans+=query(mid+1,r,rt<<1|1,a,b);
return ans;
}
signed main(){
scanf("%lld",&n);
build(1,n,1);
scanf("%lld",&m);
while(m--){
scanf("%lld%lld%lld",&k,&l,&r);
if(l>r) swap(l,r);
if(k==0) update(1,n,1,l,r);
else printf("%lld\n",query(1,n,1,l,r));
}
return 0;
}