[Lowbit]( Problem - 7116 (hdu.edu.cn) )
思路:一个数加上log次lowbit后就会成2的次方,那么用线段树维护区间和同时维护这个区间内所有的数是否是2的次方,若是,打懒标记将这个区间*2,否则暴力更新叶节点。
#include<bits/stdc++.h>
#define mid ((t[p].l+t[p].r)>>1)
#define ll long long
#define ls (p<<1)
#define rs ((p<<1)|1)
#define ll long long
#define pb push_back
using namespace std;
ll read(){ll x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*f;}
inline void Prin(ll x){if(x < 0){putchar('-');x = -x;}if(x > 9) Prin(x / 10);putchar(x % 10 + '0');}
const int qs=2e5+7;
const ll mod=998244353;
struct Tree{
int l,r;
ll val,add,tag;
#define l(x) t[x].l
#define r(x) t[x].r
#define val(x) t[x].val
#define add(x) t[x].add
#define tag(x) t[x].tag
}t[qs*4];
ll T,n,a[qs],q;
void pushup(int p) {
val(p)=(val(ls)+val(rs))%mod;
tag(p)=tag(ls)+tag(rs);
}
ll lowbit(ll x){
return (x&(-x));
}
void build(int p,int l,int r){
l(p)=l,r(p)=r; add(p)=1;
if(l==r){
val(p)=a[l];
tag(p)=lowbit(a[l])==a[l] ? 0 : 1;
return;
}
build(ls,l,mid);
build(rs,mid+1,r);
pushup(p);
}
void down(int p){
if(add(p)==1) return;
val(ls)=val(ls)*add(p)%mod;
val(rs)=val(rs)*add(p)%mod;
add(ls)=add(ls)*add(p)%mod;
add(rs)=add(rs)*add(p)%mod;
add(p)=1;
}
void update(int p,int l,int r){
// cout<<"l="<<l(p)<<" r="<<r(p)<<" val="<<val(p)<<"
";
if(l<=l(p)&&r>=r(p)){
if(tag(p)==0){
add(p)=add(p)*2%mod;
val(p)=val(p)*2%mod;
return;
}
if(l(p)==r(p)){
ll vp=lowbit(a[l(p)]);
a[l(p)]+=vp;
val(p)=a[l(p)]%mod;
if(lowbit(a[l(p)])==a[l(p)]) tag(p)=0;
return ;
}
down(p);
update(ls,l,r);
update(rs,l,r);
pushup(p);
return;
}
down(p);
if(l<=mid) update(ls,l,r);
if(r>mid) update(rs,l,r);
pushup(p);
}
ll ask(int p,int l, int r){
if(l<=l(p)&&r>=r(p)) return val(p);
down(p);
ll val=0;
if(l<=mid) val+=ask(ls,l,r);
if(r>mid) val+=ask(rs,l,r);
val%=mod;
return val;
}
int main(){
T=read();
while(T--){
n=read();
for(int i=1;i<=n;++i) a[i]=read();
build(1,1,n);
q=read();
while(q--){
int x,l,r;
x=read(),l=read(),r=read();
if(x==1){
update(1,l,r);
}
else{
ll ans=ask(1,l,r);
Prin(ans);
puts("");
}
}
}
return 0;
}