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