【BZOJ 3560】 3560: DZY Loves Math V (欧拉函数)

3560: DZY Loves Math V

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 241  Solved: 133

Description

给定n个正整数a1,a2,…,an,求

的值(答案模10^9+7)。

Input

第一行一个正整数n。
接下来n行,每行一个正整数,分别为a1,a2,…,an。

Output

仅一行答案。

Sample Input

3
6
10
15

Sample Output

1595

HINT



1<=n<=10^5,1<=ai<=10^7。共3组数据。

Source

By Jcvb

 

 

【分析】

  好好想这题就不难。

  phi是积性函数,把i1*i2*..in分解质因数,那么答案就是Πphi[xxx]

  其中一个质数p对答案的贡献就是

 

  

  因为phi[p^n]=p^n*(p-1)/p 而phi[1]=1

  所以要减一再加一smd

  然后就暴力了。

 

 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5 #include<algorithm>
 6 using namespace std;
 7 #define Maxn 100010
 8 #define LL long long
 9 #define Mod 1000000007
10 
11 int pri[Maxn],pl;
12 bool vis[Maxn];
13 
14 struct node
15 {
16     int x,y;
17 }t[80*Maxn];int len;
18 
19 bool cmp(node x,node y) {return (x.x==y.x)?(x.y<y.y):(x.x<y.x);}
20 
21 void init()
22 {
23     pl=0;
24     memset(vis,0,sizeof(vis));
25     for(int i=2;i<=Maxn-10;i++)
26     {
27         if(!vis[i]) pri[++pl]=i;
28         for(int j=1;j<=pl;j++)
29         {
30             if(pri[j]*i>Maxn-10) break;
31             vis[pri[j]*i]=1;
32             if(i%pri[j]==0) break;
33         }
34     }
35 }
36 
37 void ins(int x)
38 {
39     for(int i=1;pri[i]*pri[i]<=x;i++) if(x%pri[i]==0)
40     {
41         t[++len].x=pri[i];t[len].y=0;
42         while(x%pri[i]==0) t[len].y++,x/=pri[i];
43     }
44     if(x!=1) t[++len].x=x,t[len].y=1;
45 }
46 
47 int sum[Maxn];
48 
49 LL qpow(int x,int b)
50 {
51     LL xx=(LL)x,ans=1;
52     while(b)
53     {
54         if(b&1) ans=(ans*xx)%Mod;
55         xx=(xx*xx)%Mod;
56         b>>=1;
57     }
58     return ans;
59 }
60 
61 int main()
62 {
63     init();
64     int n;
65     scanf("%d",&n);
66     len=0;
67     for(int i=1;i<=n;i++)
68     {
69         int x;
70         scanf("%d",&x);
71         ins(x);
72     }
73     sort(t+1,t+1+len,cmp);
74     int j;
75     LL ans=1;
76     for(int i=1;i<=len;i=j+1)
77     {
78         j=i;
79         while(t[j].x==t[i].x&&j<=len) j++;j--;
80         sum[0]=1;for(int k=1;k<=t[j].y;k++) sum[k]=(sum[k-1]*t[i].x)%Mod;
81         for(int k=1;k<=t[j].y;k++) sum[k]+=sum[k-1];
82         LL now=1;
83         for(int k=i;k<=j;k++) now=(now*sum[t[k].y])%Mod;
84         ans=ans*((now-1)%Mod*(t[i].x-1)%Mod*qpow(t[i].x,Mod-2)%Mod+1)%Mod;
85     }
86     printf("%lld\n",ans);
87     return 0;
88 }
View Code

 

2017-03-23 19:39:20

 

posted @ 2017-03-23 19:39  konjak魔芋  阅读(196)  评论(0编辑  收藏  举报