• HDU7059:Counting Stars——题解


    https://acm.hdu.edu.cn/showproblem.php?pid=7059

    支持三种操作:1、区间求和 2、区间减lowbit 3、区间加$2^k(2^kle a_i<2^{k+1})$

    SB题,就是老年选手有点敲不动线段树了(现在数据结构越来越不稳了DEBUG等一年……)。

    减lowbit容易想到每个数最多减log次,因此暴力减维护对应区间是否全0即可。

    区间加$2^k$也不难发现这相当于对数的最高位*2。

    因此整体做法就是把每个数的最低位和最高位分开处理即可。

    (如果码风不好那就会像我一样DE一年的BUG……)

    #include<cmath>
    #include<queue>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N=1e5+5;
    const ll p=998244353;
    inline int read(){
        int X=0,w=0;char ch=0;
        while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
        while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        return w?-X:X;
    }
    ll qpow[N];
    void init(){
        qpow[0]=1;
        for(int i=1;i<=100000;i++){
            qpow[i]=qpow[i-1]<<1;
            qpow[i]%=p;
        }
    }
    int n,q,b[N];
    ll low[N<<2],high[N<<2],lazy[N<<2];
    bool zero[N<<2];
    ll geth(ll x){
        for(ll i=1;;++i){
            if(!(x>>i))return (1<<(i-1))&x;
        }
    }
    void build(int a,int l,int r){
        if(l==r){
            high[a]=geth(b[l]);low[a]=b[l]-high[a];zero[a]=0;
            return;
        }
        int mid=(l+r)>>1;
        build(a<<1,l,mid);build(a<<1|1,mid+1,r);
        lazy[a]=0;
        low[a]=low[a<<1]+low[a<<1|1];
        high[a]=(high[a<<1]+high[a<<1|1])%p;
        zero[a]=zero[a<<1]&zero[a<<1|1];
    }
    inline void push(int a,int l,int r,int mid){
        if(lazy[a]){
            high[a<<1]=high[a<<1]*qpow[lazy[a]]%p;
            high[a<<1|1]=high[a<<1|1]*qpow[lazy[a]]%p;
            lazy[a<<1]+=lazy[a];
            lazy[a<<1|1]+=lazy[a];
            lazy[a]=0;
        }
        return;
    }
    void modify1(int a,int l,int r,int l1,int r1){
        if(r<l1||r1<l)return;
        if(zero[a])return;
        if(l==r){
            ll del=b[l]&(-b[l]);
            b[l]-=del;
            if(!b[l]){
                high[a]=0;
                zero[a]=1;
            }else{
                low[a]-=del;
            }
            return;
        }
        int mid=(l+r)>>1;
        push(a,l,r,mid);
        modify1(a<<1,l,mid,l1,r1);modify1(a<<1|1,mid+1,r,l1,r1);
        low[a]=low[a<<1]+low[a<<1|1];
        high[a]=(high[a<<1]+high[a<<1|1])%p;
        zero[a]=zero[a<<1]&zero[a<<1|1];
    }
    void modify2(int a,int l,int r,int l1,int r1){
        if(r<l1||r1<l)return;
        if(zero[a])return;
        if(l1<=l&&r<=r1){
            ++lazy[a];
            high[a]=(high[a]<<1)%p;
            return;
        }
        int mid=(l+r)>>1;
        push(a,l,r,mid);
        modify2(a<<1,l,mid,l1,r1);modify2(a<<1|1,mid+1,r,l1,r1);
        low[a]=low[a<<1]+low[a<<1|1];
        high[a]=(high[a<<1]+high[a<<1|1])%p;
        zero[a]=zero[a<<1]&zero[a<<1|1];
    }
    ll query(int a,int l,int r,int l1,int r1){
        if(r<l1||r1<l)return 0;
        if(zero[a])return 0;
        if(l1<=l&&r<=r1){
            return (high[a]+low[a])%p;
        }
        int mid=(l+r)>>1;
        push(a,l,r,mid);
        return (query(a<<1,l,mid,l1,r1)+query(a<<1|1,mid+1,r,l1,r1))%p;
    }
    int main(){
        init();
        int T=read();
        while(T--){
            n=read();
            for(int i=1;i<=n;i++)b[i]=read();
            build(1,1,n);
            q=read();
            while(q--){
                int op=read(),l=read(),r=read();
                if(op==1){
                    printf("%d
    ",query(1,1,n,l,r));
                }
                if(op==2){
                    modify1(1,1,n,l,r);
                }
                if(op==3){
                    modify2(1,1,n,l,r);
                }
            }
        }
        return 0;
    }

    +++++++++++++++++++++++++++++++++++++++++++

     +本文作者:luyouqi233。               +

     +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

    +++++++++++++++++++++++++++++++++++++++++++

  • 相关阅读:
    正则表达式练习,持续更新中
    Jquery使用mouseenter和mouseleave实现鼠标经过弹出层且可以点击
    SQL查找 删除重复数据只保留一条
    TreeView(C#)无限目录树代码片段
    ora-01440:要减小精度或标度,则要修改的列必须为空
    SQL查询和删除重复字段的内容
    CodeSmith(C#)简单示例及相关小知识
    MSSQL 自定义函数详解
    一些精妙的sql语句收集
    134.Gas Station
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/15133764.html
Copyright © 2020-2023  润新知