玄学题… … …数论题… … …
题面给出了Ghd的定义…大概就是一个数列中超过一半的数的gcd的最大值…
看起来就像二分…但没有找出单调性
那就要拿出万能的随机化了
大概随机个10次,错误率大概就只有1/1000了QAQ
#include<bits/stdc++.h>
using namespace std;
const int randomsum=10;//随机十次
unsigned long long seed1,seed2;
void randomize(unsigned long long c,unsigned long long b)//自己写的随机化模板
{
seed1=c+b;
seed2=b*c%468562482981;//膜一个不知道是啥的数
}
unsigned long long random()//某dalao用的随机数方法
{
seed1^=seed2<<12;
seed2^=seed1>>9;
seed1^=seed2<<6;
seed2^=seed1<<12;
seed2^=seed1<<3;
seed1=~seed1;
seed2=~seed2;
seed1^=seed2^=seed1^=seed2;
return seed1;
}
long long gcd(long long a,long long b)//gcd
{
if(b==0)return a;
return gcd(b,a%b);
}
long long llmax(long long a,long long b)//long long取max
{
if(a>b)return a;else return b;
}
long long num[1000005];
int N;
long long a[1000005],b[1000005],c[1000005],answer=1,half;
void solve()
{
long long QAQ=num[(int)(random()%N+1)];//随机一个序列中的数
int i,j;
for(i=1;i<=N;i++)
a[i]=gcd(num[i],QAQ);//所有数都和这个数取一次gcd
sort(a+1,a+N+1);//拍一遍序
int top=0;
for(i=1;i<=N;i++)//去重,并记录个数
{
if(a[i]!=a[i-1])
{b[++top]=a[i];c[top]=0;}
c[top]++;
}
long long sum=0,now=-1;
for(i=1;i<=top;i++)//枚举answer
{
sum=0;
for(j=1;j<=top;j++)
if(b[j]%b[i]==0)sum+=c[j];
if(sum>=half)now=b[i];//判断answer是否成立
}
answer=llmax(answer,now);//与最终答案取大值
}
int main()
{
randomize(time(0),time(0));//随机初始化
scanf("%d",&N);
int i;
a[0]=-1;
half=(N+1)/2;//一半的大小
for(i=1;i<=N;i++)
scanf("%lld",&num[i]);
for(i=1;i<=randomsum;i++)
solve();
printf("%lld",answer);
return ~0;//QAQ
}
//因为是随机化,所以有一定的概率会…可以适当增加随机次数