本题的重要信息就是最大公约数一定是大于等于一半的a[i]拥有的,也就是说我每次随机取一个,会有50%的机会选中正确答案。
这样我只有随机化多次,就能在极大概率上获得正解。
对于一次随机化,找到所有的约数,之后用最大公约数公式找到最大的能满足条件的答案。
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=2e6+10; const int inf=0x3f3f3f3f; int tot; ll num[N]; ll a[N]; ll cnt[N]; ll gcd(ll a,ll b){ return b?gcd(b,a%b):a; } void get(ll x){ tot=0; for(ll i=1;i*i<=x;i++){ if(x%i==0){ num[++tot]=i; if(x/i!=i) num[++tot]=x/i; } } } int main(){ ios::sync_with_stdio(false); int n; cin>>n; int i; for(i=1;i<=n;i++){ cin>>a[i]; } int times=11; ll ans=0; while(times--){ ll x=a[rand()*rand()%n+1]; get(x); sort(num+1,num+1+tot); memset(cnt,0,sizeof cnt); for(i=1;i<=n;i++){ int pos=lower_bound(num+1,num+1+tot,gcd(a[i],x))-num; cnt[pos]++; } for(i=1;i<=tot;i++){ for(int j=i+1;j<=tot;j++){ if(num[j]%num[i]==0){ cnt[i]+=cnt[j]; } } } for(i=tot;i>=1;i--){ if(cnt[i]*2>=n){ ans=max(ans,num[i]); break; } } } cout<<ans<<endl; }