思想
所以就是我先通过add()函数把ai1,air2转化为二进制形式,再通过query()函数进行异或运算,再返回main函数用sum+起来。ai3,ai4利用组合排列求出来最后全部相加得出结果。
#include<bits/stdc++.h>
#define ll long long
#define int long long
using namespace std;
const int N=1e6+10;
const int mo=998244353;
int x,y,n,sum,m,k,z,a[N],b[N],c[N],d[N],key,p[N][2],temp[N][2];
//更新temp数组
void add(int x)
{
for(int i=31;i>=0;i--)
{
int xl=(x>>i)&1;//判断每一位是1还是0
temp[i][xl]++;//统计x1为1的个数,x1为0的个数
}
}
int query(int x)
{
int sum=0;
for(int i=31;i>=0;i--)//拆解为32位二进制
{
int xl=(x>>i)&1;//判断每一位上是1还是0
sum+=(1ll<<i)*temp[i][xl^1];//异或1,那么第i位是1,结果就为0,i位是0,结果就为1
sum%=mo;//值太大了,要mod
}
return sum;
}
signed main()
{
int t=1;
while(t--)
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
int sum=0;
//枚举ai1,ai2
for(int i=1;i<=n-2;i++)
{
x=(n-i)*(n-i-1)/2;//通过排列组合算出来 从n-i个元素中选两个
sum=(sum+query(a[i])*x%mo)%mo;
add(a[i]);
}
//清空
for(int i=0;i<=60;i++)
{
for(int j=0;j<2;j++)
{
temp[i][j]=0;
}
}
z=0;
//ai3的情况
for(int i=n;i>=3;i--)
{
if(i!=n)
{
x=(i-1)*(i-2)/2;//通过排列组合算出来 从i个元素中选2个
sum=(sum+query(a[i])*x%mo)%mo;
}
add(a[i]);
}
cout<<sum;
}
return 0;
}