蓝桥杯备赛:Day8-小苯的异或和

张开发
2026/4/8 3:48:17 15 分钟阅读

分享文章

蓝桥杯备赛:Day8-小苯的异或和
算法笔记小苯的异或和 (贡献法与位运算性质)1. 题目简述M-小苯的异或疑惑hard_北京信息科技大学第十五届程序设计竞赛同步赛场景给定长度为n nn的数组a aa计算所有满足1 ≤ i j ≤ n 1 \le i j \le n1≤ij≤n的( a i ⊕ a j ) (a_i \oplus a_j)(ai​⊕aj​)的总异或和。核心挑战n nn高达2 × 10 5 2 \times 10^52×105两两组合共有n ( n − 1 ) 2 \frac{n(n-1)}{2}2n(n−1)​对暴力计算会达到2 × 10 10 2 \times 10^{10}2×1010次运算必然超时。目标在O ( n ) O(n)O(n)或O ( n log ⁡ n ) O(n \log n)O(nlogn)时间内求出结果。2. 核心代码 (C 实现)#include bits/stdc.h using namespace std; typedef long long ll; void solve() { int n; if(!(cin n)) return; vectorint a(n); int total_xor 0; for(int i 0; i n; i) { cin a[i]; total_xor ^ a[i]; // 预先计算所有元素的异或总和 } // 关键逻辑判断 // 每个数 a[i] 会出现在 (n-1) 个组合中。 // 如果 (n-1) 是偶数a[i] 异或偶数次抵消为 0。 // 如果 (n-1) 是奇数a[i] 异或奇数次等价于异或 1 次。 if ((n - 1) % 2 0) { cout 0 endl; } else { cout total_xor endl; } } int main() { ios::sync_with_stdio(0); cin.tie(0), cout.tie(0); int _ 1; while(_--) { solve(); } return 0; }3. 核心考点与注意事项贡献法 (Contribution Technique)不计算每对组合的结果而是统计每个元素在最终算式中出现了多少次。异或的归零性异或运算最核心的性质是x ⊕ x 0 x \oplus x 0x⊕x0。只要某个数出现了偶数次它在异或链中就会彻底消失。组合数学计数元素a k a_kak​会和它前面的k − 1 k-1k−1个数配对也会和它后面的n − k n-kn−k个数配对。总次数 ( k − 1 ) ( n − k ) n − 1 (k-1) (n-k) n-1(k−1)(n−k)n−1次。这是一个常数意味着所有数字出现的次数是一样多的。️ 位运算基础备忘录符号操作关键特性^异或相同为 0不同为 1自反性a ⊕ b ⊕ b a a \oplus b \oplus b aa⊕b⊕ba按位与全 1 为 1常用于取位或判断奇偶x 1按位或左移x ≪ n x \ll nx≪n相当于x ⋅ 2 n x \cdot 2^nx⋅2n

更多文章