您的位置:首页 > 其它

BZOJ3560 DZY Loves Math V(欧拉函数)

2018-09-25 18:50 344 查看

  对每个质因子分开计算再乘起来。使用类似生成函数的做法就很容易统计了。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
#define N 100010
#define M 10000010
#define P 1000000007
int n,a
,prime[M>>3],id[M],v[M>>3],inv[M],cnt=0,ans=1;
bool flag[M];
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj3560.in","r",stdin);
freopen("bzoj3560.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read();
for (int i=1;i<=n;i++) a[i]=read();
inv[1]=1;
for (int i=2;i<=M-10;i++)
{
inv[i]=P-1ll*(P/i)*inv[P%i]%P;
if (!flag[i]) prime[++cnt]=i,id[i]=cnt,v[cnt]=1;
for (int j=1;j<=cnt&&prime[j]*i<=M-10;j++)
{
flag[prime[j]*i]=1;
if (i%prime[j]==0) break;
}
}
for (int i=1;i<=n;i++)
{
int x=a[i];
for (int j=1;flag[x];j++)
if (x%prime[j]==0)
{
int tot=1;
while (x%prime[j]==0) tot=(1ll*tot*prime[j]+1)%P,x/=prime[j];
v[j]=1ll*v[j]*tot%P;
}
if (x>1) v[id[x]]=1ll*v[id[x]]*(x+1)%P;
}
for (int i=1;i<=cnt;i++)
if (v[i]>1) ans=1ll*ans*(1ll*(v[i]-1)*(prime[i]-1)%P*inv[prime[i]]%P+1)%P;
cout<<ans;
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: