HDU7116lowbit(暴力+線段樹)
阿新 • • 發佈:2021-09-05
題目大意:
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\n",query(1,1,n,l,r)); } } } return 0; }