第一行一個數n(1<=n<=100000)。 接下來一行n個數ai,表示這n個數(0<=ai<=10^9)。
一行表示答案。
3 3 4 5
70
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int N = 100100;
const int M = 1000000007;
int LeftRev[32][N];
bool bit[N][32];
int main()
{
int n;
int HighestDigit = 0;
ll x;
scanf("%d", &n);
for(int i = 1; i <= n; i++)
{
scanf("%lld", &x);
int cnt = 0;
while(x)
{
if(x & 1) bit[i][cnt] = true;
x >>= 1;
cnt++;
}
HighestDigit = max(HighestDigit, cnt);
}
for(int i = 0; i < HighestDigit; i++)
{
int one = 0, zero = 0;
for(int j = 1; j <= n; j++)
{
if(bit[j][i])
{
LeftRev[i][j] = zero;
one = j;
}
else
{
LeftRev[i][j] = one;
zero = j;
}
}
}
ll ans = 0;
for(int R = 1; R <= n; R++)
{
int L = R;
int pre = R;
while(L > 0)
{
ll AndSum = 0, OrSum = 0;
int next = 0;
for(int i = 0; i < HighestDigit; i++)
{
if(bit[R][i])
{
if(L > LeftRev[i][R]) AndSum |= 1LL << i;
OrSum |= 1LL << i;
}
else
{
if(L <= LeftRev[i][R]) OrSum |= 1LL << i;
// AndSum's ith digit is zero
}
if(LeftRev[i][R] < L)
next = max(next, LeftRev[i][R]);
}
L = next;
//cout << L + 1 << ' ' << R << ' ' << AndSum << ' ' << OrSum << endl;
//system("pause");
ans = (ans + (((AndSum * OrSum) % M) * (pre - L)) % M) % M;
pre = L;
}
}
printf("%lld\n", ans);
return 0;
}