很久之前写的题,今天看到的一句话概括了这道题的精髓:
xor的每一位具有独立性,分开维护即可
10棵线段树+1e8+7,很好写很好过
#include <iostream>
#include <cstdio>
#define N 2000050
#define mod 100000007
#define mid ( (l+r)>>1 )
#define ls l,mid,(t<<1)
#define rs mid+1,r,((t<<1)^1)
using namespace std;
typedef long long LL;
int a[N],n,m,p,x,v,ll,rr;
LL ans;
struct Tree{LL siz,sum,L,R,f;}identity,S;
struct Segment_Tree{
Tree tr[N];
LL yh(int t,int p) {
return p == 0 ? tr[t].siz - tr[t].L : tr[t].siz - tr[t].R;
}
Tree mer(Tree p1,Tree p2) {
Tree tmp = identity;
tmp.siz = p1.siz + p2.siz;
tmp.f = p1.f ^ p2.f;
tmp.L = p1.L + (p1.f ? (p2.siz - p2.L) : p2.L);
tmp.R = p2.R + (p2.f ? (p1.siz - p1.R) : p1.R);
tmp.sum = (p1.sum + p2.sum) % mod;
tmp.sum = ( tmp.sum + p1.R * (p2.siz - p2.L) + p2.L * (p1.siz - p1.R) ) % mod;
return tmp;
}
void build(int l,int r,int t) {
if (l == r) {
tr[t].sum = tr[t].f = tr[t].L = tr[t].R = (a[l]&1);
tr[t].siz = 1;
return ;
}
build(ls); build(rs);
tr[t] = mer(tr[2*t],tr[2*t+1]);
}
void update(int l,int r,int t) {
if (l == r) { tr[t].sum = tr[t].f = tr[t].L = tr[t].R = (v&1); return ; }
if (p<=mid) update(ls); else update(rs);
tr[t] = mer(tr[2*t],tr[2*t+1]);
}
void query(int l,int r,int t) {
if (l >= ll && r <= rr) { S = mer(S,tr[t]); return ;}
if (ll <= mid) query(ls);
if (rr > mid) query(rs);
}
}T[11];
void solve() {
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
for (int i=0;i<10;i++) {
T[i].build(1,n,1);
for (int j=1;j<=n;j++) a[j] >>= 1;
}
scanf("%d",&m);
while (m--) {
char cmd[10]; scanf("%s",cmd+1);
if (cmd[1] == 'M') {
scanf("%d%d",&p,&x);
for (int i=0;i<10;i++) {
v = (x&1); x >>= 1;
T[i].update(1,n,1);
}
} else {
scanf("%d%d",&ll,&rr);
ans = 0LL;
for (int i=0;i<10;i++) {
S = identity;
T[i].query(1,n,1);
ans = (ans + S.sum * (1LL<<i)) % mod;
}
printf("%d\n",(int)ans);
}
}
}
int main()
{
freopen("cardcaptor.in","r",stdin);
freopen("cardcaptor.out","w",stdout);
solve();
fclose(stdin); fclose(stdout);
return 0;
}