题意:
解法:
统计所有数二进制位中0和1的数量,
对于每一个二进制位:
如果为全0或者全1,那么这一位怎么排列都可以,
否则既有0又有1,
此时我们一定要选出两个该二进制位为0的数,
一个放在b[1],一个放在b[n],
因为如果b[1]的该二进制位为1,
b[1]和(b[2],b[3]...b[3])的按位与一定是一个为0一个为1,
这样就不满足题目条件了,b[n]同理.
令mark[j]表示是否二进制第j位需要让b[1]和b[n]位0,
预处理出mark[j],
然后找出序列中有多少个数满足所有的mark[],
这些数是可以放在b[1]和b[n]的,
假设有num个数满足条件,那么答案为C(num,2)*fac[n-2],
其中fac[n-2]是n-2的阶乘.
code:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxm=2e6+5;
const int mod=1e9+7;
int cnt[33][2];
int mark[maxm];
int fac[maxm];
int a[maxm];
int n;
void init(){
fac[0]=1;
for(int i=1;i<maxm;i++)fac[i]=fac[i-1]*i%mod;
}
int cal(int n){
return n*(n-1)%mod;
}
void solve(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int j=0;j<=30;j++){
cnt[j][0]=cnt[j][1]=0;
}
for(int i=1;i<=n;i++){
for(int j=0;j<=30;j++){
cnt[j][a[i]>>j&1]++;
}
}
for(int j=0;j<=30;j++){
if(cnt[j][0]==n||cnt[j][1]==n){
mark[j]=0;
}else{
mark[j]=1;
}
}
int num=0;
for(int i=1;i<=n;i++){
int ok=1;
for(int j=0;j<=30;j++){
if(mark[j]){
if(a[i]>>j&1){
ok=0;
}
}
}
if(ok)num++;
}
int ans=cal(num)*fac[n-2]%mod;
cout<<ans<<endl;
}
signed main(){
ios::sync_with_stdio(0);
init();
int T;cin>>T;
while(T--){
solve();
}
return 0;
}