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

  

猜你喜欢

转载自www.cnblogs.com/guangheli/p/12904189.html
今日推荐