CF364D Ghd(随机化)

另一个集合\(s\)\(ghd\)\(max\{gcd(s')||s'|>=0.5|s|\}\) 给定序列\(a\),求\(ghd\)

随机化算法。因为\(|s'|\geq 0.5|S|\),所以每个元素在\(s'\)中的概率为\(0.5\),我们可以钦定一个元素令它在\(s'\)中,那么算出它和其他所有元素的\(\gcd\),用\(map\)将所有的\(\gcd\)存起来,\(first\)存值,\(second\)存这个值的出现次数。然后从大到小枚举每一个\(\gcd\),并把比它大的那些且是它倍数的\(\gcd\)的出现次数加起来,如果某一次某个\(\gcd\)出现次数大于一半,那么该答案可行

为了避免TLE加几发剪枝,比如如果随机出来的元素比最优答案小就无视,如果两个数的\(\gcd\)比最优答案小无视,从大到小枚举元素只要有一个答案成立剩下的全都可以无视。然后\(rand\)\(15\)次左右基本就能出答案了

//minamoto
#include<bits/stdc++.h>
#define R register
#define ll long long
#define fi first
#define se second
#define IT map<ll,int>::iterator
#define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
ll read(){
    R ll res,f=1;R char ch;
    while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
    for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
    return res*f;
}
char sr[1<<21],z[20];int C=-1,Z=0;
inline void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
void print(R int x){
    if(C>1<<20)Ot();if(x<0)sr[++C]='-',x=-x;
    while(z[++Z]=x%10+48,x/=10);
    while(sr[++C]=z[Z],--Z);sr[++C]='\n';
}
const int N=1e6+5;
ll a[N],ans=1,x;int n,pos;map<ll,int>mp;
ll gcd(ll x,ll y){return y?gcd(y,x%y):x;}
int main(){
//  freopen("testdata.in","r",stdin);
    srand(time(0));
    n=read();
    fp(i,1,n)a[i]=read();
    fp(T,1,15){
        pos=(1ll*rand()*RAND_MAX+rand())%n+1;
        if(a[pos]<=ans)continue;
        fp(i,1,n){
            x=gcd(a[pos],a[i]);if(x<=ans)continue;
            mp.count(x)?++mp[x]:mp[x]=1;
        }if(mp.empty())continue;
        IT it=mp.end();
        do{
            --it;if(it->fi<=ans)break;
            int cnt=0;
            for(IT itl=it;itl!=mp.end()&&(cnt<<1)<n;++itl)
                if(itl->fi%it->fi==0)cnt+=itl->se;
            if((cnt<<1)>=n){ans=it->fi;break;}
        }while(it!=mp.begin());
        map<ll,int>().swap(mp);
    }printf("%I64d\n",ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/bztMinamoto/p/10217834.html
今日推荐