• Lowbit(势能线段树)


    D. Lowbit
    time limit per test7 seconds
    memory limit per test256 megabytes
    inputstandard input
    outputstandard output
    Lucida has a sequence of n integers a1,a2,…,an. He asks you to perform two types of operations for him, which are described as follows:
    
    1. 1 L R, add lowbit(ai) to each ai in the interval [L,R].
    
    2. 2 L R, query the sum of the numbers in the interval [L,R].
    
    lowbit(x) is defined as the largest power of 2 that divides x. For example, lowbit(4)=4, lowbit(5)=1. Specially, lowbit(0)=0.
    
    Lucida wants you to give the answer modulo 998244353 for each of his queries.
    
    Input
    This problem contains multiple test cases.
    
    The first line contains a single integer T (1≤T≤20) indicating the number of test cases.
    
    For each case, the first line contains an integer n (1≤n≤105), the length of the sequence.
    
    The next line contains n integers ai (1≤ai<998244353) separated by spaces, representing the sequence.
    
    The next line contains an integer m (1≤m≤105), the number of operations.
    
    The next m lines, each line contains 3 integers op,L,R (1≤op≤2, 1≤L≤R≤n), represents one operation. The specific meaning is described above.
    
    Output
    For each query, output a line contains the answer modulo 998244353.
    
    Example
    inputCopy
    1
    5
    1 2 3 4 5
    5
    2 2 4
    1 1 3
    2 2 4
    1 1 5
    2 4 5
    outputCopy
    9
    12
    14
    View Problem
    #include <bits/stdc++.h>
    using namespace std;
    #define M 100005
    #define ri register int
    
    const int mod=998244353;
    template <class G> void read(G &x)
    {
        x=0;char ch=getchar();int f=0;
        while(ch<'0'||ch>'9'){f|=ch=='-';ch=getchar();}
        while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
        x=f?-x:x;
        return ;
    }
    
    int n,m;
    long long  val[M];
    struct dian{
        int l,r;
        long long sum;
        long long lz;
        int flag;
    }p[4*M];
    
    int ck(long long a)
    {
        if(a==(a&(-a))) return 1;
        else return 0;
    }
    void build(int l,int r,int i)
    {
        p[i].l=l,p[i].r=r;p[i].lz=1;
        if(l==r)
        {
            p[i].sum=val[l];
            p[i].flag=0;return ;
        }
        int mid=(l+r)>>1;
        build(l,mid,i<<1);
        build(mid+1,r,i<<1|1);
        p[i].sum=(p[i<<1].sum+p[i<<1|1].sum)%mod;
        p[i].flag=(p[i<<1].flag&p[i<<1|1].flag);
    }
    void downn(int i)
    {
        if(p[i].lz==1) return ;
        p[i<<1].sum=(1LL*p[i<<1].sum*p[i].lz)%mod;
        p[i<<1|1].sum=(1LL*p[i<<1|1].sum*p[i].lz)%mod;
        p[i<<1].lz=p[i<<1].lz*p[i].lz%mod;
        p[i<<1|1].lz=p[i<<1|1].lz*p[i].lz%mod;
        p[i].lz=1;
    }
    void xiu(int l,int r,int i)
    {
        if(l>p[i].r||r<p[i].l) return ;
        if(l<=p[i].l&&p[i].r<=r)
        {
            if(p[i].flag)
            {    
                p[i].sum=(1LL*p[i].sum*2)%mod;
                p[i].lz=p[i].lz*2%mod;
                return ;
            }
        }
        if(p[i].l==p[i].r)
        {
            p[i].sum=(p[i].sum+(p[i].sum&(-p[i].sum)));
            p[i].flag=ck(p[i].sum);
            return ;
        }
        downn(i);
        xiu(l,r,i<<1);xiu(l,r,i<<1|1);
        p[i].sum=(p[i<<1].sum+p[i<<1|1].sum)%mod;
        p[i].flag=(p[i<<1].flag&p[i<<1|1].flag);
    }
    long long cha(int l,int r,int i)
    {
        if(l>p[i].r||r<p[i].l) return 0;
        if(l<=p[i].l&&p[i].r<=r)
        {
            return p[i].sum;
        }
        if(p[i].lz) downn(i);
        return (cha(l,r,i<<1)+cha(l,r,i<<1|1))%mod;
    }
    int T;
    int main(){
        
        read(T);
        while(T--)
        {
            
            read(n);
            for(ri i=1;i<=n;i++) read(val[i]);
            build(1,n,1);
            read(m);
            for(ri i=1;i<=m;i++)
            {
                int a,b,c;
                read(a);read(b);read(c);
                if(a==1)
                {
                    xiu(b,c,1);
                }
                if(a==2)
                {
                    long long ans=cha(b,c,1);
                    ans=ans%mod;
                    printf("%lld\n",ans);
                }
            }    
        }
    }
    View Code

    思路: 

    • 牢牢利用lowbit的性质,当 x=lowbit时,相当于 x2, 之后每一次lowbit 都是x2.
    • 注意这个取模,不用对基本单位取模,应为他要lowbit,lz一定要取模

    反思:

    • 当答案错误时,发现没有代码错误时。
    • 就一定是 某些没有考虑完全,思路完全了吗?,一些细节完全了吗,这道题 lz要取mod,不能直接 <<lazy 这要一下子就要爆炸。
  • 相关阅读:
    AC自动机+全概率+记忆化DP UVA 11468 Substring
    java POI技术之导出数据优化(15万条数据1分多钟)
    验证IP端与数据库Ip端是否重复!!!
    JAVA中IP和整数相互转化(含有掩码的计算)
    Nginx搭建反向代理服务器过程详解
    session原理及实现共享
    Linux部署多个tomcat
    linux下怎么修改mysql的字符集编码
    linux yum 安装mysql
    VM虚拟机下的Linux不能上网
  • 原文地址:https://www.cnblogs.com/Lamboofhome/p/15994824.html
Copyright © 2020-2023  润新知