SPOJ:OR(位運算&數學指望)

Given an array of N integers A1, A2, A3…AN. If you randomly choose two indexes i ,j such that 1 ≤ i < j ≤ N, what is the expected value of Ai | Aj?ios

Input

First line contains an integer T, the number of test cases. Each test case consists of two lines. First line denotes the size of array, N and second line contains N integers forming the array.
1 ≤ T ≤ 10 
2 ≤ N ≤ 100,000 
0 ≤ Ai < 231dom

Output

For each test case, print the answer as an irreducible fraction. Follow the format of the sample output. 
The fraction p/q (p and q are integers, and both p ≥ 0 and q > 0 holds) is called irreducible, if there is no such integer d > 1 that divides both p and q separately.ide

Example

Input:
2
2
0 0
3
1 2 3

Output:
0/1
3/1

題意:給定一個數列a[],求任意兩個數a[i]和a[j]的或運算的指望(i!=j)。spa

思路:此類題已是套路了,就是每一位分別看,統計爲一位爲1和爲0的個數。而後根據XOR,或者OR的性質採起相應的措施。code

           OR的話,就是第i位的貢獻是:(C(n,2)-C(num[i],2))/C(n,2)*(1<<i) 。num[i]是第i位爲0的個數。orm

(注意,用unsigned long long)blog

#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm>
#define ll unsigned long long
using namespace std; ll F,P,G,num[33],N,a,b,c,i,j; int main() { int T,x; scanf("%d",&T); while(T--){ scanf("%lld",&N); F=0; P=(N-1)*N/2; c=N*(N-1)/2; for(i=0;i<31;i++) num[i]=0; for(i=1;i<=N;i++){ scanf("%d",&x); for(j=0;j<31;j++) if(x&(1<<j)) num[j]++; } for(i=0;i<31;i++){ F+=(P-(N-num[i])*(N-num[i]-1)/2)*(1LL<<i); } G=__gcd(F,P); F/=G; P/=G; printf("%lld/%lld\n",F,P); } return 0; }
相關文章
相關標籤/搜索