题目
思路
是一个比较简单的线段树题,线段树的原理就是分段存数据,然后通过递归实现区间操作
首先,直接进行单点修改肯定会超时
所以我们加个剪枝 优化
如果是0/1的话,再开根就没有意义了,所以如果是0或者1就return
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define lc(x) x<<1
#define rc(x) x<<1|1
const int maxn=1e5+5;
int n,m;
int v[maxn<<2];
int s[maxn<<2],ax[maxn<<2];
void pushup(int x){//往上更新数据
s[x]=s[lc(x)]+s[rc(x)];
ax[x]=max(ax[lc(x)],ax[rc(x)]);
}
void build(int x,int l,int r){//建树
if(l==r) { s[x]=ax[x]=v[l];return; }
int mid=l+r>>1;
build(lc(x),l,mid),build(rc(x),mid+1,r);
pushup(x);
}
void modify(int x,int l,int r,int L,int R){//修改操作
if(l==r) { s[x]=sqrt(s[x]),ax[x]=sqrt(ax[x]);return; }//开根操作
if(ax[x]<=1) return;//优化
int mid=l+r>>1;
if(L<=mid) modify(lc(x),l,mid,L,R);//递归
if(R>mid) modify(rc(x),mid+1,r,L,R);
pushup(x);
}
int query(int x,int l,int r,int L,int R){//查询操作
if(L<=l&&r<=R) return s[x];
int mid=l+r>>1;
int res=0;
if(L<=mid) res+=query(lc(x),l,mid,L,R);
if(R>mid) res+=query(rc(x),mid+1,r,L,R);
return res;
}
signed main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>v[i];
build(1,1,n);
cin>>m;
while(m--){
int if_case;cin>>if_case;
int l,r;cin>>l>>r;
if(l>r) swap(l,r);
switch (if_case){
case 1:cout<<query(1,1,n,l,r)<<endl;break;
case 0:modify(1,1,n,l,r);break;
}
}
return 0;
}