Main idea of the title:
Omit, if you don't know, please read the topic carefully.
Thoughts on problem solving:
1: Find the sum of intervals [L,R]
2: XOR operations are performed on every number of intervals [L,R].
Previous interval summation, the required segment tree, node maintenance is the numerical value, the line segment tree can be summed;
But if every node in this question is a maintained value? Then XOR operations need to be modified at a single point.
For this problem, single point modification is not feasible.
But how to maintain this segment tree?
The XOR operations we perform are binary XOR operations on digits.
The treatment is as follows:
The following operations are performed on the data:
Convert each number to a binary number:
The range of data is 1e5, so each number can be converted to 19 bits at most.
Maintain 20 segment trees, and each segment tree maintains the number of these data at 1 bit.
For the number of XOR operations, it becomes binary. Each bit only affects the current bit, but not the other bits.
The corresponding line segment trees are crossed or crossed respectively.
Sum time: The number of 1 in the statistical interval multiplied by the corresponding (1 i);
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int num=1e5+10;
const int bit=20;
struct node
{
int L,R,s,i;
}a[33][num<<2];
int b[num];
void update(int f,int k)
{
a[f][k].s=a[f][k<<1].s+a[f][k<<1|1].s;
a[f][k].i=0;
return;
}
void build(int f,int k,int L,int R)
{
a[f][k].L=L;a[f][k].R=R;
a[f][k].s=0;a[f][k].i=0;
if(L==R)
{
a[f][k].s = (b[L]>>f)&1;
return ;
}
int mid=(L+R)>>1;
build(f,k<<1,L,mid);
build(f,k<<1|1,mid+1,R);
update(f,k);
return ;
}
void pushdown(int f,int k)
{
a[f][k<<1].i^=1;
a[f][k<<1|1].i^=1;
a[f][k].i=0;
a[f][k<<1].s=(a[f][k<<1].R-a[f][k<<1].L+1) - a[f][k<<1].s;
a[f][k<<1|1].s=(a[f][k<<1|1].R-a[f][k<<1|1].L+1) - a[f][k<<1|1].s;
return;
}
void change(int f,int k,int L,int R,int x)
{
if(a[f][k].L>=L&&a[f][k].R<=R)
{
a[f][k].s=(a[f][k].R-a[f][k].L+1)-a[f][k].s;
a[f][k].i^=x;
return ;
}
if(a[f][k].i) pushdown(f,k);
int mid=(a[f][k].L+a[f][k].R)>>1;
if(L<=mid) change(f,k<<1,L,R,x);
if(R>mid) change(f,k<<1|1,L,R,x);
update(f,k);
return ;
}
LL search(int f,int k,int L,int R)
{
if(a[f][k].L>=L&&a[f][k].R<=R)
{
return a[f][k].s;
}
if(a[f][k].i) pushdown(f,k);
int mid=(a[f][k].L+a[f][k].R)>>1;
LL ans=0;
if(L<=mid) ans+=search(f,k<<1,L,R);
if(R>mid) ans+=search(f,k<<1|1,L,R);
return ans;
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&b[i]);
for(int i=0;i<=bit;i++)
{
build(i,1,1,n);
}
int id,L,R,x;
for(int j=1;j<=m;j++)
{
scanf("%d",&id);
if(id==1){
scanf("%d%d",&L,&R);
LL ans=0;
for(int i=0;i<=bit;i++)
{
ans += (1LL<<i)*(search(i,1,L,R));
}
printf("%lld\n",ans);
}
else if(id==2){
scanf("%d%d%d",&L,&R,&x);
for(int i=0;i<=bit;i++)
{
int t=(x&1);
if(t)
change(i,1,L,R,t);
x>>=1;
}
}
}
return 0;
}