• HDU7116lowbit(暴力+线段树)


    题目大意:
    lowbit(x)是x的最低位1 区间修改 ai+lowbit(ai) 区间和查询 n,m<1e5
    题解:
    一个数x最多加log(x)次lowbitx就会变成2的幂,2的幂加lowbitx相当于x2,标记区间是否都为2的幂,若是则区间每个数x2,不是则暴力修改。

    #include<bits/stdc++.h>
    using namespace std;
    #define LL long long
    
    const int N=1e5+7;
    
    const int mod=998244353;
    
    int n;
    int m,od,l,r;
    LL a[N];
    
    struct Tree
    {
        int l,r;
        LL sum;
        bool gg;
        LL flag;
    }tr[N<<2];
    
    
    LL lowbit(LL x)
    {
        return x&(-x);
    }
    
    void pushup(int rt)
    {
        tr[rt].sum=(tr[rt<<1].sum%mod+tr[rt<<1|1].sum%mod)%mod;
        tr[rt].gg=min(tr[rt<<1].gg,tr[rt<<1|1].gg);
    }
    
    void pushdown(int rt)
    {
        if(tr[rt].flag==1)return ;
        tr[rt<<1].sum=tr[rt<<1].sum*tr[rt].flag%mod;
        tr[rt<<1|1].sum=tr[rt<<1|1].sum*tr[rt].flag%mod;
        tr[rt<<1].flag=tr[rt<<1].flag*tr[rt].flag%mod;
        tr[rt<<1|1].flag=tr[rt<<1|1].flag*tr[rt].flag%mod;
        tr[rt].flag=1;
    }
    
    void build(int rt,int l,int r)
    {
        tr[rt].l=l;tr[rt].r;tr[rt].flag=1;
        if(l==r)
        {
            tr[rt].sum=a[l];
              tr[rt].gg=0;
            return ;
        }
        int mid=(l+r)>>1;
        build(rt<<1,l,mid);
        build(rt<<1|1,mid+1,r);
        pushup(rt);
    }
    
    void update(int rt,int l,int r,int ql,int qr)
    {
        if(ql<=l&&qr>=r&&tr[rt].gg==1)
        {
            tr[rt].sum=tr[rt].sum*2%mod;
            tr[rt].flag=tr[rt].flag*2%mod;
            return ;
        }
        if(l==r)
        {
            tr[rt].sum=tr[rt].sum+lowbit(tr[rt].sum);
            if(tr[rt].sum==lowbit(tr[rt].sum)) tr[rt].gg=1;
            return ;
        }
        pushdown(rt);
        int mid=(l+r)>>1;
        if(ql<=mid) update(rt<<1,l,mid,ql,qr);
        if(qr>mid) update(rt<<1|1,mid+1,r,ql,qr);
        pushup(rt);
    }
    
    LL query(int rt,int l,int r,int ql,int qr)
    {
        if(ql<=l&&qr>=r) return tr[rt].sum;
        pushdown(rt);
        LL res=0;
        int mid=(l+r)>>1;
        if(ql<=mid) res=(res%mod+query(rt<<1,l,mid,ql,qr)%mod)%mod;
        if(qr>mid) res=(res%mod+query(rt<<1|1,mid+1,r,ql,qr)%mod)%mod;
        return res;
    }
    
    int main()
    {
        int T;
        cin>>T;
        while(T--)
        {
            scanf("%d",&n);
            for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
            build(1,1,n);
            scanf("%d",&m);
            while(m--)
            {
                scanf("%d%d%d",&od,&l,&r);
                if(od==1)
                {
                    update(1,1,n,l,r);
                }else
                {
                    printf("%lld
    ",query(1,1,n,l,r));
                }
            }
        }
        return 0;
    }
    
    
  • 相关阅读:
    Day 20 初识面向对象
    Day 16 常用模块
    Day 15 正则表达式 re模块
    D14 模块 导入模块 开发目录规范
    Day 13 迭代器,生成器,内置函数
    Day 12 递归,二分算法,推导式,匿名函数
    Day 11 闭包函数.装饰器
    D10 函数(二) 嵌套,命名空间作用域
    D09 函数(一) 返回值,参数
    Day 07 Day08 字符编码与文件处理
  • 原文地址:https://www.cnblogs.com/zzyh/p/15230374.html
Copyright © 2020-2023  润新知