题意:
就是给你n个数,一共去C(n,3)个三元组,计算axorbxorc,然后把所有的值加起来,问你是多少,对mod取余。
思考:
位运算的题一直是我的弱项,其实也做过不少了,无非就是按每一位去考虑。刚开始看到这题感觉没想法,去做别的了,然后最后再来看这个题,还是没想法。又自己问了问自己,如果是两元组呢,你怎么做,想到这我就想到了,按每一位看,选一个是1的选一个是0的异或起来才有贡献,想到这就明白了。对于三元组,就是选两个0和一个1,还有就是选3个1。组后计算答案就行了,值得注意的是,一定要多取模,能取模就取模,不要乘一起了再取模!!!。
代码:
int T,n,m,k;
int va[N];
int cnt[N];
int fact[N],infact[N];
int ksm(int a,int b)
{
int sum = 1;
while(b)
{
if(b&1) sum = sum*a%mod;
a = a*a%mod;
b >>= 1;
}
return sum;
}
void init()
{
fact[0] = infact[0] = 1;
for(int i=1;i<N;i++)
{
fact[i] = fact[i-1]*i%mod;
infact[i] = infact[i-1]*ksm(i,mod-2)%mod;
}
}
int C(int a,int b)
{
if(a<b) return 0;
return fact[a]*infact[b]%mod*infact[a-b]%mod;
}
signed main()
{
IOS;
init();
cin>>n;
for(int i=1;i<=n;i++) cin>>va[i];
for(int i=1;i<=n;i++)
{
for(int j=0;j<64;j++)
cnt[j] += (va[i]>>j)&1;
}
int ans = 0;
for(int i=0;i<64;i++)
{
int l = cnt[i],r = n-l;
ans = (ans+C(l,3)%mod*ksm(2,i)%mod)%mod;
ans = (ans+C(r,2)%mod*l%mod*ksm(2,i)%mod)%mod;
}
cout<<ans%mod;
return 0;
}
总结:
反正相信自己能做出来,多思考思考,想想这个题目的简化版怎么做,一步一步的去解决。