Pinely Round 3 B. Make Almost Equal With Mod (位运算 + 数学 +构造)

给你一个由不同正整数组成的数组 a 1 , a 2 , ... , a n a_1,a_2,...,a_n a1,a2,...,an 。你必须做下面的操作次:

  • 选择一个正整数 k k k ;
  • 对于从 1 1 1 到 n n n 的每个 i i i ,将 a i a_i ai 替换为 a i m o d k † a_i mod k† aimodk† 。

求 k k k 的值,使得 1 ≤ k ≤ 1 0 18 1≤k≤10^{18} 1≤k≤1018 和数组 a 1 , a 2 , ... , a n a_1,a_2,...,a_n a1,a2,...,an 在操作结束时包含个完全的 2 2 2 不同值。可以证明,在问题的约束条件下,至少有一个这样的 k k k 始终存在。如果有多个解,可以打印其中任意一个。

a m o d b a mod b amodb 表示 a a a 除以 b b b 后的余数。例如
7 m o d 3 = 1 因为 7 = 3 ⋅ 2 + 1 7 mod 3=1 因为 7=3⋅2+1 7mod3=1因为7=3⋅2+1 。
15 m o d 4 = 3 因为 15 = 4 ⋅ 3 + 3 15 mod 4=3 因为 15=4⋅3+3 15mod4=3因为15=4⋅3+3 。
21 m o d 1 = 0 因为 21 = 21 ⋅ 1 + 0 21 mod 1=0 因为 21=21⋅1+0 21mod1=0因为21=21⋅1+0 。

输入

每个测试包含多个测试用例。第一行包含测试用例的数量 t ( 1 ≤ t ≤ 500 ) t ( 1≤t≤500 ) t(1≤t≤500)。测试用例说明如下。

每个测试用例的第一行包含一个整数 n ( 2 ≤ n ≤ 100 ) n ( 2≤n≤100 ) n(2≤n≤100) - 数组的长度 a a a 。

每个测试用例的第二行包含 n n n 个整数 a 1 , a 2 , ... , a n ( 1 ≤ a i ≤ 1 0 17 ) a_1,a_2,...,a_n ( 1≤a_i≤10^{17} ) a1,a2,...,an(1≤ai≤1017)------数组的初始状态。保证所有的 a i a_i ai 都是不同的。

请注意,所有测试用例中 n n n 的总和不受限制。

输出

对于每个测试用例,输出一个整数: k ( 1 ≤ k ≤ 1 0 18 ) k ( 1≤k≤10^{18} ) k(1≤k≤1018),这样在操作结束时,数组 a 1 , a 2 , ... , a n a_1,a_2,...,a_n a1,a2,...,an 恰好包含 2 2 2 个不同的值。


首先可以想到,所有正整数可以分为偶数和奇数,那么如果这段序列里既有奇数又有偶数,那么 k k k 就一定可以直接取 2 2 2,那么其他情况就是只有偶数或者只有奇数。

由于插入时全部都是2的某次方,那么就对应了二进制的某一个数位,那么只需要枚举所有 2 0 2^0 20 ~ 2 5 7 2^57 257 作为 k k k ,然后查看是否有能够满足题目需求的序列就可以了。

如果把这个问题放到二进制的角度来看,那么就相当于去取插入的所有数的二进制形式的后缀,枚举所有后缀长度直到找到能够使得后缀的种类只会有两种。


CODE:

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
const int N = 110;
#define int long long
#define ll long long
#define endl '\n'
int a[N];
void solve(){
    int n;cin >> n;
    bool ok1 = 0;
    bool ok2 = 0;
    for(int i = 1;i <= n;i++){
        cin >> a[i];
        if(a[i]&1)ok1 = 1;
        if(a[i]&1==0)ok2 = 1;
    }

    if(ok1 && ok2){
        cout << 2 << endl;
        return;
    }

    for(int i = 1;i <= 57;i++){
        int cnt = 0;
        map<int,bool>vis;
        int t = (1ll << i);
        for(int i = 1;i <= n;i++){
            if(!vis[a[i]%t]){
                cnt++;
                vis[a[i]%t] = 1;
            }
        }
        if(cnt == 2){
            cout << t << endl;
            return;
        }
    }
}

signed main(){
    int T;cin >> T;
    while(T--){
        solve();
    }
    return 0;
}
相关推荐
Escalating_xu26 分钟前
【C++入门基础(下)】默认参数、函数重载、引用、inline 与 nullptr
android·c++·redis
艾莉丝努力练剑42 分钟前
【AI大模型接入SDK】Provider分析与实现
c++·人工智能·学习·面试·大模型·llm
土司大王7 小时前
LeetCode hot100——对称二叉树
算法·leetcode·职场和发展
sali-tec7 小时前
C# 基于OpenCv的视觉工作流-章106-差值追踪
图像处理·人工智能·opencv·算法·计算机视觉
Navigator_Z7 小时前
LeetCode //C - 1208. Get Equal Substrings Within Budget
c语言·算法·leetcode
手写码匠7 小时前
Dify 多 Agent 工具权限与安全沙箱实战:让智能体“有能力,但不越权“
人工智能·深度学习·算法·aigc
黎阳之光7 小时前
打破堆场感知黑盒:黎阳之光视频孪生,构建港口码头网格化透明管控新体系
大数据·人工智能·算法·安全·数字孪生
大模型码小白8 小时前
AI 对话流性能调优:万级消息的虚拟滚动落地
java·大数据·前端·javascript·人工智能·算法·机器学习
老当益壮梁奶奶8 小时前
Linux软件编程学习笔记(七):线程分离与线程间通信详解
linux·c语言·c++·笔记·学习
sel_99 小时前
【多轮对话论文导读(三)】多轮对话与Agent论文阅读笔记:用户模拟、轨迹生成与长期记忆
论文阅读·人工智能·笔记·深度学习·算法·机器学习