• 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;
    }
    
    
  • 相关阅读:
    .Net中的装箱和拆箱
    使用GetThumbnailImage进行图片缩放操作
    潭州课堂25班:Ph201805201 第二课:数据类型和序列类型 (课堂笔记)
    公开课 之 心蓝 数据分析 (课堂笔记)
    潭州课堂25班:Ph201805201 第一课:环境搭建 (课堂笔记)
    Maven笔记
    java中Swing编程再度练习篇
    Swing编程练习。可能这篇会有错误哦
    Swing
    Swing编程把图片放入frame里。先不作为背景图片
  • 原文地址:https://www.cnblogs.com/zzyh/p/15230374.html
Copyright © 2020-2023  润新知