Memphis loves xor very musch.Now he gets an array A.The length of A is n.Now he wants to know the sum of all (lowbit(AiAi xor AjAj)) (i,j∈[1,n])(i,j∈[1,n])
We define that lowbit(x)=2k2k,k is the smallest integer satisfied ((xx and 2k2k)>0)
Specially,lowbit(0)=0
Because the ans may be too big.You just need to output ansans mod 998244353
Input
Multiple test cases, the first line contains an integer T(no more than 10), indicating the number of cases. Each test case contains two lines
The first line has an integer nn
The second line has nn integers A1A1,A2A2....AnAn
n∈[1,5∗104]n∈[1,5∗104],Ai∈[0,229]Ai∈[0,229]
Output
For each case, the output should occupies exactly one line. The output format is Case #x: ans, here x is the data number begins at 1.
Sample Input
2
5
4 0 2 7 0
5
2 6 5 4 0
Sample Output
Case #1: 36
Case #2: 40
题意:给你一个序列[a, a + n),求所有lowbit(Ai xor Aj)的和。即Ai^Aj的值第一个1出现的位置k,求k<<1的和。
思路:这道题的话,因为异或运算相同为0,不同为1。lowbit函数是找一个数表示成2进制数,从最低位开始第一个不为0的数之前有k个0,则结果为2^k。比如2,4。 2:010 4:100 我们发现(右数,最右边为第0位)从第0位开始起,他们第1位不同,所以我们可以判断第1位之前都为0,那么lowbit值为2^1。所以我们可以建立一个字典树,每输入一个数对其做一次计算,加上之前的和他不同的个数,因为是没有顺序的,最后结果乘以2。
AC代码:
#include <bits/stdc++.h>
typedef long long ll;
const int maxx=50010;
const int maxn=2;
const int inf=0x3f3f3f3f;
const int mod=998244353;
using namespace std;
int Trie[30*maxx][maxn];
int num[30*maxx];
int color[110];
int a[maxx];
int k;
ll ans;
void init()
{
memset(Trie,0,sizeof(Trie));
memset(num,0,sizeof(num));
k=0;
}
int newnode()
{
num[++k]=0;
Trie[k][0]=Trie[k][1]=0;
return k;
}
void insert(ll w)
{
int p=0;
for(int i=0; i<30; i++)
{
int c=(w>>i)&1;
if(Trie[p][c])
{
ans+=color[i]*num[Trie[p][c^1]];
ans%=mod;
}
else
{
Trie[p][c]=newnode();
Trie[p][c^1]=newnode();
}
p=Trie[p][c];
num[p]++;
}
}
int main()
{
color[0]=1;
for(int i=1; i<=30; i++)
color[i]=2*color[i-1];
int t;
scanf("%d",&t);
int cas=1;
while(t--)
{
init();
int n;
scanf("%d",&n);
ans=0;
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
insert(a[i]);
}
ans=ans*2%mod;
printf("Case #%d: %lld\n",cas++,ans);
}
return 0;
}