区间问题向 下放操作 上去考虑,当子节点全部都是 1 / 0 时,此时不需要操作更新
const int N=1e6+5;
int n,m,t;
int i,j,k;
int a[N];
struct Node
{
int l, r;
ll sum;
bool f; //所有子节点都 <=1 则为 1 ;
}node[N<<2];
void push_up(int id)
{
if(node[id<<1].f && node[id<<1|1].f) node[id].f=1;
else node[id].f=0;
node[id].sum=node[id<<1].sum+node[id<<1|1].sum;
}
void push_down(int id)
{
if(node[id].f) return;
int l=node[id].l,r=node[id].r;
if(l==r){
node[id].sum=sqrt(node[id].sum);
if(node[id].sum<=1) node[id].f=1;
return ;
}
push_down(id<<1);
push_down(id<<1|1);
push_up(id);
}
void build(int l,int r,int id)
{
node[id].l=l;
node[id].r=r;
if(l==r){
node[id].sum=a[l];
if(a[l]<=1) node[id].f=1;
else node[id].f=0;
} else{
int mid=l+r>>1;
build(l,mid,id<<1);
build(mid+1,r,id<<1|1);
push_up(id);
}
}
void update(int l,int r,int id)
{
if(node[id].f) return ;
int L=node[id].l, R=node[id].r;
if(L>=l && r>=R){
push_down(id); //相当于 node[id].update
return ;
} else{
int mid=L+R>>1;
//push_down(id);
if(mid>=l) update(l,r,id<<1);
if(r>=mid+1) update(l,r,id<<1|1);
push_up(id);
}
}
ll query(int l,int r,int id)
{
int L=node[id].l, R=node[id].r;
if(L>=l && r>=R){
return node[id].sum;
} else{
int mid=L+R>>1;
ll ans=0;
if(mid>=l) ans+=query(l,r,id<<1);
if(r>=mid+1) ans+=query(l,r,id<<1|1);
return ans;
}
}
int main()
{
//IOS;
while(~sd(n)){
for(i=1;i<=n;i++) sd(a[i]);
build(1,n,1);
sd(m);
while(m--){
int l,r,x,tag;
sddd(tag,l,r);
if(tag==2){
update(l,r,1);
} else if(tag==1){
pll( query(l,r,1) );
}
}
}
//PAUSE;
return 0;
}