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
#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); } } } }
思路:
- 牢牢利用lowbit的性质,当 x=lowbit时,相当于 x2, 之后每一次lowbit 都是x2.
- 注意这个取模,不用对基本单位取模,应为他要lowbit,lz一定要取模
反思:
- 当答案错误时,发现没有代码错误时。
- 就一定是 某些没有考虑完全,思路完全了吗?,一些细节完全了吗,这道题 lz要取mod,不能直接 <<lazy 这要一下子就要爆炸。