样例没调过,蒟蒻已经炸了,悬关感谢,请大佬爆踩
#include<bits/stdc++.h>
#define debug cout << "OK" << endl;
#define MAXN int(1e5 + 10)
#define MAXM int(1e6 + 10)
using namespace std;
int n, m;
int a[MAXN];
long long tree[MAXN << 2][20], mark[MAXN << 2];
inline int lson(const int &rt)
{
return rt << 1;
}
inline int rson(const int &rt)
{
return rt << 1 | 1;
}
inline void push_up_sum(const int &rt)
{
for(int i = 0; i < 20; i++)
{
tree[rt][i] = tree[lson(rt)][i] + tree[rson(rt)][i];
}
}
inline void push_down(const int &rt, const int &l, const int &r)
{
int mid = (l + r) >> 1;
for(int i = 0; i < 20; i++)
{
if((mark[rt] >> i) & 1)//区间取反
{
tree[lson(rt)][i] = (mid - l + 1) - tree[lson(rt)][i];
tree[rson(rt)][i] = (r - mid) - tree[rson(rt)][i];
}
}
mark[lson(rt)] ^= mark[rt];
mark[rson(rt)] ^= mark[rt];
mark[rt] = 0;//清空标记
}
inline void build(const int &rt, const int &l, const int &r)
{
if(l == r)
{
for(int i = 0; i < 20; i++)
{
tree[rt][i] = (a[l] >> i) & 1;
}
return ;
}
int mid = (l + r) >> 1;
build(lson(rt), l, mid);
build(rson(rt), mid + 1, r);
push_up_sum(rt);
}
inline void update(const int &l, const int &r, const int &rt, const int &cl, const int &cr, const int &d)
{
if(cl > r || cr < l)
{
return ;
}
else if(cl <= l && cr >= r)
{
for(int i = 0; i < 20; i++)
{
if((d >> i) & 1)//区间取反
{
tree[rt][i] = (r - l + 1) - tree[rt][i];
}
}
mark[rt] ^= d;
return ;
}
else
{
push_down(rt, l, r);
update(l, (l + r) >> 1, lson(rt), cl, cr, d);
update(1 + (l + r) >> 1, r, rson(rt), cl, cr, d);
push_up_sum(rt);
return ;
}
}
inline long long query(const int &l, const int &r, const int &rt, const int &cl, const int &cr)
{
if(l > cr || r < cl)
{
return 0;
}
else if(cl <= l && cr >= r)
{
long long ans = 0, base = 1;
for(int i = 0; i < 20; i++)
{
ans += base * tree[rt][i];
base <<= 1;
}
return ans;
}
else
{
push_down(rt, l, r);
return query(l, (l + r) >> 1, lson(rt), cl, cr) + query(1 + (l + r) >> 1, r, rson(rt), cl, cr);
}
}
int main()
{
cin >> n;
for(int i = 1; i <= n; i++)
{
scanf("%d", a + i);
}
build(1, 1, n);
cin >> m;
while(m--)
{
int x, l, r, d;
scanf("%d %d %d", &x, &l, &r);
if(x == 1)
{
printf("%lld\n", query(1, n, 1, l, r));
}
else
{
scanf("%d", &d);
update(1, n, 1, l, r, d);
}
}
return 0;
}