然而我太懒了……没有打哈希。
直觉告诉我第二个答案是选择的k个数的差的gcd,那么对于每一个质因数,记录一下序列中能被这个质数整除的差的gcd,然后就可以了
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define N 100010
#define M 10000010
using namespace std;
int n,Ans1,Ans2,Maxx;
int A[N],B[N];
int p[M],v[M],vis[M],f[M];
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void rea(int &x){
char c=nc(); x=0;
for(;c>'9'||c<'0';c=nc());for(;c>='0'&&c<='9';x=x*10+c-'0',c=nc());
}
inline void First(){
for(int i=2;i<=Maxx;i++){
if(!p[i]) p[++*p]=i,v[i]=*p;
for(int j=1;j<=*p&&p[j]*i<=Maxx;j++){
p[p[j]*i]=1; v[p[j]*i]=j;
if(i%p[j]==0) break;
}
}
}
int gcd(int x,int y){
if(!x||!y) return x+y;
return y?gcd(y,x%y):x;
}
int main(){
rea(n);
for(int i=1;i<=n;i++) rea(A[i]),Maxx=max(Maxx,A[i]);
First();
for(int K=1;K<=4;K++){
int x=A[rand()%n+1],cnt=0,w=0,Max=0,nAns=0;
for(int i=1;i<=n;i++)
if(A[i]!=x) B[++cnt]=A[i]<x?(x-A[i]):(A[i]-x);
else w++;
for(int i=1;i<=*p;i++) vis[i]=f[i]=0;
for(int i=1;i<=cnt;i++){
int now=B[i];
for(;now^1;now/=p[v[now]]){
vis[v[now]]++;
f[v[now]]=gcd(f[v[now]],B[i]);
int y=p[v[now]];
while((now/y)%y==0) now/=y;
}
}
for(int i=1;i<=*p;i++)
if(vis[i]>vis[Max]||(vis[i]==vis[Max]&&f[i]>nAns)) Max=i,nAns=f[i];
if(vis[Max]+w>Ans1) Ans1=vis[Max]+w,Ans2=nAns;
else if(vis[Max]+w==Ans1&&nAns>Ans2) Ans2=nAns;
}
return printf("%d %d\n",Ans1,Ans2),0;
}