蓝桥&搜狐畅游 异或与求和

43 阅读1分钟

image.png 思想

image.png image.png 所以就是我先通过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;
 }