给你一个由不同正整数组成的数组 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:
#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;
}