CF364D Ghd 随机化
由于题目要求所选集合大小要大于等于 $\frac{n}{2}$,所以你随便选一个数至少有一半的概率在集合里.
那么我们就随机选 10 个左右的数,成功率是 $1-\frac{1}{2^{10}}.$
code:
#include<iostream>
#include<cstdio>
#include<time.h>
#include<stdlib.h>
#include<cmath>
#include<algorithm>
#include<cstring>
#define N 1000007
#define ll long long
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
int n;
ll a[N],ay[N],cnt[N];
int ran() { return (ll)rand()*rand()%n+1; }
ll gcd(ll a,ll b) { return !b?a:gcd(b,a%b); }
int main()
{
// setIO("input");
srand(time(NULL));
scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%I64d",&a[i]);
ll maxx=0;
for(int T=1;T<11;++T)
{
int pos=ran(),sz=0;
ll x=a[pos];
for(ll i=1;i*i<=x;++i)
{
if(x%i==0)
{
ay[++sz]=i;
if(x/i!=i) ay[++sz]=x/i;
}
}
sort(ay+1,ay+1+sz);
memset(cnt,0,sizeof(cnt));
for(int i=1;i<=n;++i)
{
int p=lower_bound(ay+1,ay+1+sz,gcd(a[i],x))-ay;
++cnt[p];
}
for(int i=1;i<=sz;++i)
{
for(int j=i+1;j<=sz;++j)
if(a[j]%a[i]==0) cnt[i]+=cnt[j];
}
for(int i=sz;i>=1;--i)
if(cnt[i]*2>=n) { maxx=max(maxx,ay[i]); break; }
}
printf("%I64d\n",maxx);
return 0;
}

浙公网安备 33010602011771号