题意:求区间[l,r]所有子区间异或和
思路:对前缀异或和b[i],如果b[i]==1,那它前面的0位置x,[x+1,i]这段区间异或和必为1,b[i]==0同理,那只要再分别对前缀异或和的0,1分别在做一次前缀和就好了
Song Zha Zha has an 111-indexed array A . Li Zha Zha has QQQ queries . Each query has two integers LLL, RRR , asking Ran Zha Zha to do the following thing .First , find all subintervals of [L,R][L,R][L,R] . Then calculate their xor sum . For example .
A=1,2,3A={1,2,3}A=1,2,3 , L=1L=1L=1, R=3R=3R=3.
All subintervals of [1,3][1,3][1,3] are [1,1],[2,2],[3,3],[1,2],[2,3],[3,3][1,1],[2,2],[3,3],[1,2],[2,3],[3,3][1,1],[2,2],[3,3],[1,2],[2,3],[3,3] .Their xor sum = 1+2+3+11 + 2 + 3 + 11+2+3+1 xor 2+22 + 22+2 xor 3+13 + 13+1 xor 222 xor 333 .
Xor means exclusive or . (^
in C++ or Java )
Input
The input contains multiple test cases.
First line contains an integer TTT (1≤T≤10)(1 \le T \le 10)(1≤T≤10) , which is the number of test cases .
In each test case:
The first line contains two integers NNN, QQQ. (1≤N,Q≤100000)(1 \le N,Q \le 100000)(1≤N,Q≤100000) . NNN is the length of the array AAA .
Then one line contains NNN integer indicating A[i]A[i]A[i] . (1≤i≤N,0≤A[i]≤1000000)(1 \le i \le N , 0 \le A[i] \le 1000000) (1≤i≤N,0≤A[i]≤1000000).
Then QQQ lines follow . Each line two integer L,RL,RL,R , means that there’s a query [L,R][L,R][L,R] . (1≤L≤R≤N)(1 \le L \le R \le N)(1≤L≤R≤N).
OutputFor each query, print the answer mod 100000000710000000071000000007.
样例输入
1 3 1 1 2 3 1 3
样例输出
10
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<string>
#include<string.h>
#include<map>
#define ll long long
//#define ll int
#include <iostream>
#include <math.h>
using namespace std;
#define maxn 100005
ll a[maxn],b[maxn][35],s[maxn][35],c0[maxn][35],c1[maxn][35];
#define mod 1000000007
int main()
{
ll t;
scanf("%lld",&t);
while(t--)
{
memset(b,0,sizeof(b));
memset(s,0,sizeof(s));
memset(c1,0,sizeof(c1));
memset(c0,0,sizeof(c0));
ll n,q;
scanf("%lld %lld",&n,&q);
for(ll i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
for(ll j=0;j<=30;j++)
{
if((a[i]>>j)&1)
{
b[i][j]=b[i-1][j]^1;
}
else b[i][j]=b[i-1][j];
s[i][j]=s[i-1][j]+b[i][j];
if(b[i][j]&1)
{
c1[i][j]=c1[i-1][j]+i-s[i-1][j];
c0[i][j]=c0[i-1][j];
}
else
{
c1[i][j]=c1[i-1][j];
c0[i][j]=c0[i-1][j]+s[i-1][j];
}
//printf("b[%lld][%lld]=%lld s[%lld][%lld]=%lld c0[%lld][%lld]=%lld c1[%lld][%lld]=%lld\n",i,j,b[i][j],i,j,s[i][j],i,j,c0[i][j],i,j,c1[i][j]);
}
}
while(q--)
{
ll l,r,ans=0;
scanf("%lld %lld",&l,&r);
for(ll i=0;i<=30;i++)
{
ll x=0,y=0,w=s[r][i]-s[l-1][i];
if(l==1)
{
x=c1[r][i];
y+=c0[r][i];
}
else
{
x+=c1[r][i]-c1[l-1][i]-w*(l-1-s[l-2][i]);
y+=c0[r][i]-c0[l-1][i]-(r-l+1-w)*(s[l-2][i]);
}
//printf("i=%lld w=%lld x=%lld y=%lld ans=%lld\n",i,w,x,y,ans);
ans+=(1ll<<i)%mod*(x+y)%mod;
ans%=mod;
}
printf("%lld\n",ans);
}
}
}
/*
333
3 3333
1 2 3
*/