【BZOJ2818】Gcd(莫比乌斯反演,欧拉函数)

题意:给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的
数对(x,y)有多少对

1<=N<=10^7

思路:莫比乌斯反演,同BZOJ2820……

 

 1 const max=10000000;
 2 var sum:array[0..max]of int64;
 3     prime,flag,f,mu:array[0..max]of longint;
 4     n,m,i,j,t,v,cas:longint;
 5  
 6 function clac(n:longint):int64;
 7 var x,i,pos:longint;
 8 begin
 9  clac:=0; i:=1;
10  while i<=n do
11  begin
12   x:=n div i;
13   pos:=n div x;
14   clac:=clac+(sum[pos]-sum[i-1])*x*x;
15   i:=pos+1;
16  end;
17 end;
18  
19 begin
20  
21  mu[1]:=1;
22  for i:=2 to max do
23  begin
24   if flag[i]=0 then
25   begin
26    inc(m); prime[m]:=i;
27    mu[i]:=-1;
28   end;
29   j:=1;
30   while (j<=m)and(prime[j]*i<=max) do
31   begin
32    t:=prime[j]*i; flag[t]:=1;
33    if i mod prime[j]=0 then
34    begin
35     mu[t]:=0; break;
36    end;
37    mu[t]:=-mu[i];
38    inc(j);
39   end;
40  end;
41  for i:=1 to m do
42   for j:=1 to max div prime[i] do
43   begin
44    t:=prime[i]*j;
45    f[t]:=f[t]+mu[j];
46   end;
47  for i:=1 to max do sum[i]:=sum[i-1]+f[i];
48  read(n);
49  writeln(clac(n));
50  
51 end.

 

惊奇地发现,自己两年前用欧拉函数的方法过掉了此题……

From hzwer

枚举每个素数,然后每个素数p对于答案的贡献就是(1 ~ n / p) 中有序互质对的个数
而求1~m中有序互质对x,y的个数,可以令y >= x, 当y = x时,有且只有y = x = 1互质,当y > x时,确定y以后符合条件的个数x就是phiy
所以有序互质对的个数为(1 ~ n/p)的欧拉函数之和乘2减1(要求的是有序互质对,乘2以后减去(1, 1)多算的一次)
那么就只需要先筛出欧拉函数再求个前缀和就可以了

posted on 2017-04-05 09:53  myx12345  阅读(274)  评论(0编辑  收藏  举报

导航