【BZOJ2818】Gcd (欧拉函数)

  网址:http://www.lydsy.com/JudgeOnline/problem.php?id=2818

  一道数论裸题,欧拉函数前缀和搞一下就行了。

  小于n的gcd为p的无序数对,就是phi(1~n/p)的和,因为如果gcd(x,y)=p那么必有gcd(x/p,y/p)=1

  转化成有序数对就可以把无序数对的个数*2-1(减1是因为有一个数对是(p,p))

代码:

var p,phi:array[0..10000010]of longint;
  s:array[0..10000010]of int64;
  b:array[0..10000010]of boolean;
  n,m,i,j,k,t:longint;
  ans:int64;
begin
  read(n); t:=0;
  for i:=2 to n do b[i]:=true;
  b[1]:=false; phi[1]:=1;
  for i:=2 to n do begin
    if b[i] then begin
      phi[i]:=i-1; inc(t); p[t]:=i;
    end;
    for j:=1 to t do begin
      if i*p[j]>n then break;
      b[i*p[j]]:=false;
      if i mod p[j]=0 then begin
        phi[i*p[j]]:=phi[i]*p[j];
        break;
      end;
      phi[i*p[j]]:=phi[i]*phi[p[j]];
    end;
  end;
  ans:=0;
  for i:=1 to n do
    s[i]:=s[i-1]+phi[i];
  for i:=1 to t do
    ans:=ans+s[n div p[i]]*2-1;
  writeln(ans);
end.
View Code

 

posted @ 2017-03-11 11:45  QuartZ_Z  阅读(215)  评论(0编辑  收藏  举报