CF364D Ghd(随机化)

本题的重要信息就是最大公约数一定是大于等于一半的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;
}
View Code

 

posted @ 2020-10-13 20:29  朝暮不思  阅读(119)  评论(0编辑  收藏  举报