首先这道题的中文意思

alt 下面是题目给的公式(看不懂也没关系) alt

输入描述

第一行包含一个整数 n (2≤n≤10^15) 表示粒子的个数。 第二行包括n个整数 a1,a2...an(0≤ai<2^15) 表示第i个粒子所携带的能量。

输出描述

为一个不可化简的分数形式a/b(b>0)要确保gcd(a,b)=1或者当a=0时,b=1。

解题思路

这道题有 的位运算所以我们将它先化成二级制。
如3 5两个数字 011和101进行上述2则运算,结果为001和111,然后001和111进行运算结果依旧为001和111。我们可以发现他们的和没有变化都为8,换句话说就是“1”的位置发生了变化,而发生了一次变化后也不会再发生变化即两个值恒稳定。 接下来看样例:
输入:5
1 2 3 4 5
输出:54/5
则二进制为:
001
010
011
100
101
为了让他们不再发生碰撞即值稳定,我们将“1”的位置移到一起:
000
000
001
111
111
这个时候值就稳定了,接下来就是算方差了。 为了节省时间复杂度以及空间复杂度(代码少,懒得写)就用下述这个公式
方差=每个数的平方的平均数-平均数的平方

   int sum=0,ans=0,cnt=0;
  for(int i=1;i<=n;i++)
  {
  	sum+=a[i];
    cnt+=a[i]*a[i];//每个数的平方
  }
  //ans=cnt/n-sum/n*sum/n这边为了防止小数出现我们乘上n*n
  ans=cnt*n-sum*sum;
  //最后在求出gcd即可

最后给出代码

#include<bits/stdc++.h>
using namespace std;
#define ll  long long
ll n;
ll a[100100];
ll b[20];
int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        int x;
        cin>>x;
        int k=0;
        while(x){
            b[k]+=x%2;//将他们二进制的“1”累加起来
            x/=2;
            k++;
        }
    } 
    ll sum=0,summ=0,ans=0;
    for(int i=1;i<=n;i++){ //将二进制换成10进制
        for(int j=15;j>=0;j--){//这边范围是2^15次所以循环15
            if(b[j]){
                a[i]=a[i]*2+1;
                b[j]--;
            }
            else a[i]*=2;
        }
        sum+=a[i];
        summ+=a[i]*a[i];
    }
    ans=summ*n-sum*sum;
    ll g=__gcd(ans,n*n);
    cout<<ans/g<<"/"<<n*n/g;
}