题意:有n个互不相同的数,问是否存在一个模数M使得a[i]%M后有一个区间绝对众数。
分析:如果存在这样的M,那么随机选取一个数选到众数的概率有1/2,两个就是1/4。设这两个数为x,y,有x%M=y%M。令z=|x-y|,那么z%M=0。考虑枚举z的质因子看看是否满足条件,外面再枚举随机次数,复杂度为O(T*logA*N),但A在1e9级别,如果你不想使用PollardRho,那么只能根号枚举z的因子。理论上复杂度为O(T*sqrt(A)*N),显然会寄,但直觉上随机选取x,y的∑z不会太大,数据也卡不了,可以先在Custom Test上测一测。测完平均在200ms左右。
代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
//#define int __int128
#define pii pair<int,int>
#define endl '\n'//interactive questions require endl to refresh
#define cout cout<<setprecision(15)
const int mod=998244353;
const int maxn=1e6+5;
int a[maxn];
int n;
void check(int p)
{
if(p<3) return;
int val=0,cnt=0;
for(int i=1;i<=n;i++)//摩尔投票法
{
int now=a[i]%p;
if(cnt==0) val=now,cnt=1;
else
{
if(now==val) cnt++;
else cnt--;
}
}
cnt=0;
for(int i=1;i<=n;i++) if(a[i]%p==val) cnt++;
if(cnt>n/2)
{
cout<<p<<endl;
exit(0);
}
}
void solve()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
mt19937 rng(time(0));
for(int t=1;t<=100;t++)
{
int x=a[rng()%n+1],y=a[rng()%n+1];
int z=abs(x-y);
for(int i=1;i*i<=z;i++)
{
if(z%i==0) check(i),check(z/i);
}
}
cout<<-1<<endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t=1;
// cin>>t;cin.ignore();//use before getline
while(t--) solve();
}