E. Serval and Modulo
思路
数学不好想不出来
a i a_i ai 的总和与 b i b_i bi 的总和之间的差总是k的倍数。
注意到对于所有 n ≤ 1 0 10 n \leq 10^{10} n≤1010,恒有 d ( n ) ≤ 2304 d(n) \leq 2304 d(n)≤2304,其中 d ( n ) d(n) d(n) 表示 n n n 的约数个数。
如果存在这样的魔法数字 k k k,当 Δ ≠ 0 \Delta \neq 0 Δ=0 时,它将是 Δ = ∑ a i − ∑ b i \Delta = \sum a_i - \sum b_i Δ=∑ai−∑bi 的一个约数,或者它可以是任意一个大于所有 a i a_i ai 的整数。因此,我们可以检查 Δ \Delta Δ的所有约数,从而得到一个时间复杂度为 O ( ∑ ( n ⋅ d ( ∑ a i ) + ∑ a i ) ) O\left(\sum (n \cdot d(\sum a_i) + \sqrt{\sum a_i})\right) O(∑(n⋅d(∑ai)+∑ai)) 的解法,其中 d ( n ) d(n) d(n) 表示 n n n 的约数个数。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define endl '\n'
#define int long long
#define pb push_back
#define pii pair<int,int>
#define FU(i, a, b) for(int i = (a); i <= (b); ++ i)
#define FD(i, a, b) for(int i = (a); i >= (b); -- i)
const int MOD = 1e9+7;
const int INF = 1e9;
int a[10005],b[10005];
int cnt[1000005];
int n,sum1=0,sum2=0;
bool check(int k) {
for (int i = 1; i <= n; i++)
cnt[a[i] % k]++;
for (int i = 1; i <= n; i++)
if (--cnt[b[i]] < 0) {
cnt[b[i]] = 0;
for (int i = 1; i <= n; i++)
cnt[a[i] % k] = 0;
return 0;
}
return 1;
}
void solve() {
sum1=0,sum2=0;
cin>>n;
FU(i,1,n){
cin>>a[i];
sum1+=a[i];
}
FU(i,1,n){
cin>>b[i];
sum2+=b[i];
}
int s=sum1-sum2;
if(s==0){
if(check(INF)){
cout<<INF<<endl;
}else{
cout<<"-1\n";
}
return;
}
for (int i = 1; i * i <= s; i++)
if (s % i == 0) {
if (check(i)) {
cout<<i<<endl;
return;
}
if (i <= 1e6 && check(s / i)) {
cout<<s/i<<endl;
return;
}
}
cout<<"-1\n";
}
signed main() {
cin.tie(0)->ios::sync_with_stdio(0);
int T = 1;
cin >> T;
while (T--) {
solve();
}
return 0;
}