牛客小白月赛 103 C 题题解

题目链接

题目大意

给定一个正整数 n n n,求 mex ( { i ⊕ j ∣ i ∈ [ 1 , n ] , j ∈ [ 1 , n ] } ) \text{mex}(\lbrace i \oplus j \mid i \in [1, n], \ j \in [1, n] \rbrace) mex({i⊕j∣i∈[1,n], j∈[1,n]})。

其中 mex \text{mex} mex 表示集合中未出现的最小非负整数。

数据范围

  • 1 ≤ n ≤ 1 0 18 . 1 \leq n \leq 10^{18}. 1≤n≤1018.

Solution

要能异或出 1 1 1,最小的两个数都必须是 2 ⊕ 3 2 \oplus 3 2⊕3,所以 n ≤ 2 n \leq 2 n≤2 的 mex \text{mex} mex 都是 1 1 1.

下面讨论 n > 2 n > 2 n>2 的情况, 1 1 1 肯定能被表示出来。

取 m m m 满足 2 m − 1 < n ≤ 2 m 2^{m - 1} < n \leq 2^m 2m−1<n≤2m,用归纳法。初始时只有 [ 1 , 2 ) [1, 2) [1,2) 能被表示。

取 k = 1 k = 1 k=1,

  • 现在 [ 1 , 2 ) [1, 2) [1,2) 以内的数都可以被表示,
  • 将这些数都 ⊕ 2 \oplus 2 ⊕2, 会得到 [ 2 + 1 , 2 2 ) [2 + 1, 2^2) [2+1,22),
  • 再通过 ( 2 + 1 ) ⊕ 1 (2 + 1) \oplus 1 (2+1)⊕1 得到 2 2 2,这样就扩展到 [ 1 , 2 2 ) [1, 2^2) [1,22).
[ suppose \text{suppose} suppose: 下面的 i < m i < m i<m]

设 k = i − 1 k = i - 1 k=i−1 时能扩展到 [ 1 , 2 i ) [1, 2^i) [1,2i)。

那么 k = i k = i k=i 时,

  • 现在 [ 1 , 2 i ) [1, 2^i) [1,2i) 以内的数都可以被表示,
  • 将这些数都 ⊕ 2 i \oplus 2^i ⊕2i, 会得到 [ 2 i + 1 , 2 i + 1 ) [2^i + 1, 2^{i + 1}) [2i+1,2i+1),
  • 再通过 ( 2 i + 1 ) ⊕ 1 (2^i + 1) \oplus 1 (2i+1)⊕1 得到 2 i 2^i 2i,这样就扩展到 [ 1 , 2 i + 1 ) [1, 2^{i + 1}) [1,2i+1).

所以我们得到, k = m − 1 k = m - 1 k=m−1 时,可以扩展到 [ 1 , 2 m ) [1, 2^m) [1,2m)。

如果再取 k = m k = m k=m,分类讨论:

  • n < 2 m n < 2^m n<2m, 我们无法进行第二步: 【将这些数都 ⊕ 2 m \oplus 2^m ⊕2m】,
  • n = 2 m n = 2^m n=2m,我们可以进行第二步,得到 [ 2 m + 1 , 2 m + 1 ) [2^m + 1, 2^{m + 1}) [2m+1,2m+1),
    • 但是无法进行第三步: 【再通过 ( 2 m + 1 ) ⊕ 1 (2^m + 1) \oplus 1 (2m+1)⊕1 得到 2 m 2^m 2m】.

综上,取 m m m 满足 2 m − 1 < n ≤ 2 m 2^{m - 1} < n \leq 2^m 2m−1<n≤2m, mex = 2 m \text{mex} = 2^m mex=2m。

时间复杂度 O ( log ⁡ n ) O(\log n) O(logn)

Code

cpp 复制代码
#include <bits/stdc++.h>

using i64 = long long;

void solve() {
    i64 n;
    std::cin >> n;
    
    if (n <= 2) {
        std::cout << 1 << "\n";
    } else {
        int k = std::__lg(2 * n - 1);
        std::cout << (1LL << k) << "\n";   
    }
}

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    
    int T;
    std::cin >> T;
    
    while (T--) {
        solve();
    }
    
    return 0;
}
相关推荐
小郭团队41 分钟前
2_1_七段式SVPWM (经典算法)算法理论与 MATLAB 实现详解
嵌入式硬件·算法·硬件架构·arm·dsp开发
充值修改昵称1 小时前
数据结构基础:从二叉树到多叉树数据结构进阶
数据结构·python·算法
Deepoch1 小时前
Deepoc数学大模型:发动机行业的算法引擎
人工智能·算法·机器人·发动机·deepoc·发动机行业
点云SLAM1 小时前
C++内存泄漏检测之Windows 专用工具(CRT Debug、Dr.Memory)和Linux 专业工具(ASan 、heaptrack)
linux·c++·windows·asan·dr.memory·c++内存泄漏检测·c++内存管理
浅念-2 小时前
C语言小知识——指针(3)
c语言·开发语言·c++·经验分享·笔记·学习·算法
Hcoco_me2 小时前
大模型面试题84:是否了解 OpenAI 提出的Clip,它和SigLip有什么区别?为什么SigLip效果更好?
人工智能·算法·机器学习·chatgpt·机器人
BHXDML2 小时前
第九章:EM 算法
人工智能·算法·机器学习
却道天凉_好个秋3 小时前
目标检测算法与原理(三):PyTorch实现迁移学习
pytorch·算法·目标检测
无限进步_3 小时前
【C++】大数相加算法详解:从字符串加法到内存布局的思考
开发语言·c++·windows·git·算法·github·visual studio
C+-C资深大佬4 小时前
C++ 数据类型转换是如何实现的?
开发语言·c++·算法