大牛博客:https://blog.csdn.net/FirstLucker/article/details/47128347
下面是看了大牛的博客后,自己依着思路推的
zstu的推式子:
hdu的话,最后注意有
2
n
=
∑
i
=
0
n
C
n
k
2^n=\sum_{i=0}^nC_n^k
2n=∑i=0nCnk
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int mod = 258280327;
const int N = 1e5+10;
int prime[N];
ll h[N];
ll bin[N];
int tmp_val[N];
int cnt[N];
ll jc[N];
ll inv[N];//i的逆元
ll fac_inv[N]; //i!的逆元
void get_prime()
{
bin[0]=1;
bin[1]=2;
jc[0]=1;
jc[1]=1;
h[1]=1;
inv[0]=1;
inv[1]=1;
fac_inv[0]=1;
fac_inv[1]=1;
for(int i=2;i<N;i++)
{
bin[i]=bin[i-1]*2%mod;
jc[i]=jc[i-1]*i%mod;
inv[i]=(mod-mod/i)*inv[mod%i]%mod;
fac_inv[i]=fac_inv[i-1]*inv[i]%mod;
if(!prime[i])
{
prime[++prime[0]]=i;
h[i]=i-1;
}
for(int j=1;j<=prime[0]&&i*prime[j]<N;j++)
{
prime[i*prime[j]]=1;
if(i%prime[j]==0)
{
h[i*prime[j]]=prime[j]*h[i]%mod;
break;
}
h[i*prime[j]]=(prime[j]-1)*h[i]%mod;
}
}
}
void solve(int n,int max_val)
{
for(int i=1;i<=max_val;i++)
{
cnt[i]=0;
for(int j=i;j<=max_val;j+=i)
{
cnt[i]+=tmp_val[j];
}
}
ll zstu=0,hdu=0;
for(int d=1;d<=max_val;d++) if(cnt[d])
{
zstu=(zstu+h[d]*jc[cnt[d]]%mod*jc[n+1]%mod*fac_inv[cnt[d]-1]%mod*inv[n-cnt[d]+2]%mod)%mod;
hdu=(hdu+h[d]*cnt[d]%mod*bin[(cnt[d]-1)]%mod)%mod;
}
// cout<<zstu<<" "<<hdu<<endl;
if(zstu==hdu)
printf("Equal %lld\n",hdu);
else if(zstu<hdu)
printf("Mr. Hdu %lld\n",hdu);
else
printf("Mr. Zstu %lld\n",zstu);
}
int main()
{
get_prime();
int n,x;
while(~scanf("%d",&n))
{
memset(tmp_val,0,sizeof(tmp_val));
int max_val=0;
for(int i=0;i<n;i++)
{
scanf("%d",&x);
tmp_val[x]++;
max_val=max(max_val,x);
}
solve(n,max_val);
}
return 0;
}