2017 西安区域赛 g Sum of xor sum

题意:求区间[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
*/

猜你喜欢

转载自blog.csdn.net/qq_43497140/article/details/106943488
sum