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; }