题意:给定整数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)多算的一次)
那么就只需要先筛出欧拉函数再求个前缀和就可以了

 
 1 var b,prime,phi:array[1..10000000]of longint;
 2     s:array[0..10000000]of int64;
 3     ans:int64;
 4     i,j,m,n:longint;
 5  
 6 begin
 7  
 8  readln(n);
 9  b[1]:=1; phi[1]:=1;
10  for i:=2 to n do
11  begin
12   if b[i]=0 then
13   begin
14    inc(m); prime[m]:=i; phi[i]:=i-1;
15   end;
16   for j:=1 to m do
17   begin
18    if i*prime[j]>n then break;
19    b[i*prime[j]]:=1;
20    if i mod prime[j]=0 then
21    begin
22     phi[i*prime[j]]:=phi[i]*prime[j];
23     break;
24    end
25     else phi[i*prime[j]]:=phi[i]*(prime[j]-1);
26  
27   end;
28  end;
29  
30  for i:=1 to n do s[i]:=s[i-1]+phi[i];
31  for i:=1 to m do ans:=ans+s[n div prime[i]]*2-1;
32  writeln(ans);
33  
34 end.