#10128. 「一本通 4.3 练习 2」花神游历各国

本文主要探讨了「一本通 4.3 练习 2」中的花神游历各国问题,该问题涉及到区间内数值的平方根求和。通过使用线段树优化,可以有效地处理区间标记和查询,特别是当需要判断区间内所有数值是否为0,1时,以及进行扩展%运算的情况。文章阐述了解题思路和算法实现的关键点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#10128. 「一本通 4.3 练习 2」花神游历各国(题目链接)

大意:区间开根号,询问区间和

laz 标记区间是否全为 0,1

扩展 % 运算是最坏为 n/2的

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+500;
#define ll long long
#define ls rt<<1,l,mid
#define rs rt<<1|1,mid+1,r
ll tre[maxn<<2],laz[maxn<<2];
int n,m;
ll mp[maxn];
void build(int rt,int l,int r){
    laz[rt] = 0;
    if(l==r){
        tre[rt] = mp[l];
        if(tre[rt]==1||tre[rt]==0) laz[rt]=1;
        return ;
    }
    int mid = l+r>>1;
    build(ls);build(rs);
    tre[rt]=tre[rt<<1]+tre[rt<<1|1];
    if(laz[rt<<1]&&laz[rt<<1|1]) laz[rt]=1;
}
ll qur(int rt,int l,int r,int a,int b){
    if(l>=a&&r<=b) return tre[rt];
    int mid = l+r>>1;
    ll an=0;
    if(a<=mid) an+=qur(ls,a,b);
    if(b>mid) an+=qur(rs,a,b);
    return an;
}
void upda(int rt,int l,int r,int a,int b){
    if(laz[rt]==1)return ;
    if(l==r){
        tre[rt] = (ll)sqrt(tre[rt]);
        if(tre[rt]==1||tre[rt]==0) laz[rt]=1;
        return ;
    }
    int mid = l+r>>1;
    if(a<=mid) upda(ls,a,b);
    if(b>mid) upda(rs,a,b);
    tre[rt]=tre[rt<<1]+tre[rt<<1|1];
    if(laz[rt<<1]&&laz[rt<<1|1]) laz[rt]=1;//0 1都不用再开
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;++i) scanf("%lld",&mp[i]);
    build(1,1,n);
    scanf("%d",&m);
    int a,b,c;
    for(int i=0;i<m;++i){
        scanf("%d%d%d",&a,&b,&c);
        if(b>c) swap(b,c);
        if(a-1){
            upda(1,1,n,b,c);
        }
        else{
            printf("%lld\n",qur(1,1,n,b,c));
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值