zoukankan      html  css  js  c++  java
  • 【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)多算的一次)
    那么就只需要先筛出欧拉函数再求个前缀和就可以了

  • 相关阅读:
    面试题58 二叉树的下一个结点
    面试题57 删除链表中重复的结点
    面试题56 链表中环的入口结点
    面试题55 字符流中第一个不重复的字符
    面试题54 表示数值的字符串
    面试题50 树中两个结点的最低公共祖先
    面试题53 正则表达式匹配
    面试题52 构建乘积数组
    面试题51 数组中重复的数字
    Qt链接库出错version Qt_5 not defined
  • 原文地址:https://www.cnblogs.com/myx12345/p/6667441.html
Copyright © 2011-2022 走看看