问题描述
-
•输入:一个数组包含 n个正整数。
-
•要求:从数组中任取三个不同的数,计算每个三元组的异或值(即 a⊕b⊕c),并将所有三元组的异或值求和。
-
•输出:求和结果对 109+7取模的值
const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;
void (async function () {
// Write your code here
let params = [];
while ((line = await readline())) {
let tokens = line.split(" ");
// let a = parseInt(tokens[0]);
// let b = parseInt(tokens[1]);
// console.log(a + b);
params.push(tokens);
}
// console.log(params)
let n = BigInt(params[0][0]);
let arr = params[1].map((v) => BigInt(v));
const MOD = 1000000007n; // 使用BigInt表示模数
/**
* 快速幂函数,计算 base^exp % mod
* 使用BigInt处理大数运算
*/
function quickPow(base, exp, mod) {
let res = 1n;
base = base % mod;
while (exp > 0) {
if (exp & 1n) {
res = (res * base) % mod;
}
base = (base * base) % mod;
exp = exp >> 1n;
}
return res;
}
/**
* 计算组合数 C(a, b) % MOD
* 使用BigInt参数,处理大整数组合数
*/
function nCr(n, r) {
if (r < 0n || r > n) return 0n;
if (r === 0n || r === n) return 1n;
if (r > n - r) r = n - r; // 利用组合数性质优化
let numerator = 1n;
let denominator = 1n;
for (let i = 0n; i < r; i++) {
numerator = (numerator * (n - i)) % MOD;
denominator = (denominator * (i + 1n)) % MOD;
}
// 使用费马小定理求分母的模逆元,将除法转换为乘法
return (numerator * quickPow(denominator, MOD - 2n, MOD)) % MOD;
}
/**
* 计算异或和之和的主函数
*/
function xorSumSum(nums) {
// 统计每位1的个数,最多考虑64位
const cnt = new Array(64).fill(0n);
for (const num of nums) {
let temp = num;
// 处理BigInt的二进制位
for (let k = 0; k < 64; k++) {
if (temp & 1n) {
cnt[k]++;
}
temp = temp >> 1n;
if (temp === 0n) break;
}
}
let ans = 0n;
let base = 1n; // 2^k,使用BigInt
for (let k = 0; k < 64; k++) {
const c1 = cnt[k]; // 当前位为1的个数
const c0 = n - c1; // 当前位为0的个数
// 计算两种情况的三元组数量
const case1 = nCr(c1, 3n); // 三个1的情况
const case2 = (nCr(c0, 2n) * c1) % MOD; // 一个1和两个0的情况
const triples = (case1 + case2) % MOD;
ans = (ans + base * triples) % MOD;
base = (base * 2n) % MOD; // 更新位权重
}
return Number(ans); // 最终结果在Number安全范围内,可转换回Number
}
console.log(xorSumSum(arr)); // 输出: 10
})();