<JZOJ5943>树
一开始t了五个点我就一脸懵逼
然后 发现高级操作...
就是那个tor的数组2333
可以让一些不需要改的不再去改啦
位运算果然是神奇的东西XD
魔性哈哈哈
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #define rint register int #define MOD 998244353 template <class T>inline void read(T &X) { X=0;int W=0;char ch=0; while(!isdigit(ch))W|=ch=='-',ch=getchar(); while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar(); X=W?-X:X;return; } int n,Q,k; long long ans(0),ans2(0),tree[400010],tpow[400010],tor[400010],a[100010]; void build(int l,int r,int pos) { if(l==r) { tree[pos]=a[l]; tpow[pos]=(a[l]*a[l])%MOD; tor[pos]=a[l]; return; } int mid=l+r>>1; build(l,mid,pos<<1); build(mid+1,r,pos<<1|1); tree[pos]=tree[pos<<1]+tree[pos<<1|1]; tpow[pos]=(tpow[pos<<1]+tpow[pos<<1|1])%MOD; tor[pos]=(tor[pos<<1]|tor[pos<<1|1]); } void query(int l,int r,int L,int R,int pos) { if(L<=l && r<=R) { ans+=tree[pos]; ans2=(ans2+tpow[pos])%MOD; return; } int mid=l+r>>1; if(L<=mid)query(l,mid,L,R,pos<<1); if(R>mid)query(mid+1,r,L,R,pos<<1|1); } void change(int l,int r,int L,int R,int pos) { if((tor[pos]&(~k))==0)return; if(l==r) { tree[pos]=tree[pos]&k; a[l]=a[l]&k; tor[pos]=a[l]; tpow[pos]=(a[l]*a[l])%MOD; return; } int mid=l+r>>1; if(L<=mid)change(l,mid,L,R,pos<<1); if(R>mid)change(mid+1,r,L,R,pos<<1|1); tree[pos]=tree[pos<<1]+tree[pos<<1|1]; tpow[pos]=(tpow[pos<<1]+tpow[pos<<1|1])%MOD; tor[pos]=(tor[pos<<1]|tor[pos<<1|1]); } int main() { // freopen("seg.in","r",stdin); // freopen("seg.out","w",stdout); read(n); for(rint i=1;i<=n;++i)read(a[i]); build(1,n,1); read(Q); while(Q--) { int num,l,r; read(num); if(num==1) { read(l),read(r),read(k); change(1,n,l,r,1); continue; } else { read(l),read(r); ans=0;ans2=0; query(1,n,l,r,1); if(num==2) { printf("%lld\n",ans); continue; } if(num==3) { ans%=MOD; ans=(2*ans2%MOD*(r-l+1)%MOD+2*ans%MOD*ans)%MOD; printf("%lld\n",ans); continue; } } } }