• bnu——GCD SUM (莫比乌斯反演)


    题目:GCD SUM

    题目链接:http://www.bnuoj.com/v3/problem_show.php?pid=39872

    算法:莫比乌斯反演、优化

     1 #include<stdio.h>
     2 #define N 100001
     3 typedef long long LL;
     4 bool pri[N]={0};
     5 int prim[N],po=0;
     6 int mu[N];
     7 LL f[N],ff[N];       //缩短时间
     8 /*
     9   莫比乌斯函数mu[i]的定义:
    10   1. 如果 i 是素数,那么mu[i]为-1;
    11   2. 如果 i 是由多个不同的素数组成的,那么mu[i]为-1或者1,取决于质因子的数量,奇数就为-1,偶数为1
    12   3. 如果 i 不满上面的条件,那么mu[i]为0,比如mu[4]=0;
    13   用途:想要判断1~m中有多少数与i互质,那么首先计算出i的质因子,采用容斥定理做,排除掉所有质因子的倍数,再加上被重复计算的
    14   比如i=6、m=20时,首先排除2的倍数,再排除3的倍数,现在6的倍数被排除两次,就加上6的倍数数量。
    15 */
    16 void Init()
    17 {
    18   mu[1]=1;
    19   for(int i=2;i<N;i++)
    20   {
    21     if(!pri[i])
    22     {
    23       prim[po++]=i;
    24       mu[i]=-1;
    25     }
    26     for(int j=0;j<po;j++)
    27     {
    28       LL tmp=i*prim[j];
    29       if(tmp>=N) break;
    30       pri[tmp]=1;
    31       mu[tmp]=mu[i]*-1;
    32       if(i%prim[j]==0)
    33       {
    34         mu[tmp]=0;
    35         break;
    36       }
    37     }
    38   }
    39   f[0]=ff[0]=0;
    40   //f[]:mu的前缀和
    41   for(int i=1;i<N;i++)
    42   {
    43     f[i]=f[i-1]+mu[i];
    44     ff[i]=ff[i-1]+mu[i]*i;
    45   }
    46 }
    47 int min(int n,int m)
    48 {
    49   return n>m?m:n;
    50 }
    51 int main()
    52 {
    53   Init();
    54   int n,m;
    55   while(scanf("%d%d",&n,&m)!=EOF)
    56   {
    57     LL ans=0,ansx=0,ansy=0;
    58     int t=min(n,m);
    59     int j=1;
    60     /*
    61       简化前:
    62       for(int i=1;i<=t;i++)
    63       {
    64         ans+=mu[i]*(n/i)*(m/i);
    65         可简化原因:(n/i)*(m/i)虽然i一直在变化,但很多时候是相等的,比如15/8等于1,一直到15/15还是等于1。。。
    66         ansx+=mu[i]*(m/i)*(i+(n/i)*i)*(n/i)/2;
    67         ...
    68       }
    69       n/i:得到值,随着i的增大,如果这个值一直不变,那么这些可以和在一起算。
    70       n/(n/i):得到上面值得最大i,从上面的i到现在的i=n/(n/i),之间的n/i,都等于n/i
    71     */
    72     for(int i=1;i<=t;i=j+1)
    73     {
    74       j=min(n/(n/i),m/(m/i));
    75       ans+=(f[j]-f[i-1])*(n/i)*(m/i);
    76       ansx+=(ff[j]-ff[i-1])*(m/i)*(1+(n/i))*(n/i)/2;
    77       ansy+=(ff[j]-ff[i-1])*(n/i)*(1+(m/i))*(m/i)/2;
    78     }
    79     printf("%lld %lld %lld
    ",ans,ansx,ansy);
    80   }
    81   return 0;
    82 }
  • 相关阅读:
    区块链python演示
    网页H5图片预览滑动模仿新浪微博插件
    AngularJS
    实现A Painless Q-learning Tutorial (深度学习笔记二)
    python线性拟合数据(深度学习笔记一)
    雪花特效登录页面
    ASP.NET Core中使用NLog记录日志
    EFCore中代码优先锲约和数据类型与数据库的对应关系
    所有数据库连接字符串示例
    看到12_234_678差点怀疑人生的事儿
  • 原文地址:https://www.cnblogs.com/hchlqlz-oj-mrj/p/5052699.html
Copyright © 2020-2023  润新知