牛客小白月賽25 J.異或和之和
題目描述
給一個數組,數組內有 個正整數。
求這些數任取3個數異或運算後求和的值。
也就是說,取一共 個三元組,計算這些三元組內部異或,之後求和。(具體操作可以見樣例描述)
由於該值可能過大,輸出其對 取模的值。
輸入描述:
第一行一個正整數 。
接下來有 個正整數 ()
輸出描述:
任取三個數、三元組內部位異或後求和對取模的值。
示例1
輸入
4
3 4 5 6
輸出
10
看到異或就是明顯的位運算啦~
位運算的精髓就是用一個數組 存儲答案~
我們考慮三個數抑或和爲 的情況,只有兩種:,
那麼我們可以計算出答案每一位的 的種類,用排列組合即可
有兩個坑點:
- 上面的排列組合是可以直接死算的,但是取模會有問題,我也是試了很多種寫法才弄對,所以還是建議寫一個求組合數的函數
- 此坑點見代碼註釋
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
ll cnt[100]={0};
ll k,n,ans=0;
ll power(ll a,ll b){return b?power(a*a%mod,b/2)*(b%2?a:1)%mod:1;}
void f(ll k){
ll pos=0;
while(k){
if(k&1) cnt[pos]++;//這裏寫成cnt[pos++]++;就錯了,應該是優先級的問題,我吐了🤮
pos++;
k/=2;
}
}
main(){
cin>>n;
for(ll i=0;i<n;i++){
cin>>k;
f(k);
}
for(ll i=0;i<100;i++){
ll p=((n-cnt[i])*(n-cnt[i]-1)*cnt[i]/2+cnt[i]*(cnt[i]-1)*(cnt[i]-2)/6)%mod;
ans=(ans+power(2,i)*p)%mod;
}
cout<<ans;
}