莫比乌斯反演模版

//--莫比乌斯反演函数--//
//说明:利用线性素数筛选顺便求了个mu
//注释部分为求从区间[1,b]和区间[1,d]中取两个数,互质对数O(n^0.5)
//复杂度:O(n)
int mu[N];
//int sum[N];

void mobus()
{
    bool mark[N];
    int prime[N];
    int pcnt=0;
    memset(mark,0,sizeof(mark));
    mu[1] = 1;
    for(int i=2;i<N;i++)
    {
        if(mark[i] == 0)
        {
            prime[pcnt++] = i;
            mu[i] = -1;
        }
        for(int j=0;j<pcnt && i*prime[j]<N;j++)
        {
            int tmp = i*prime[j];
            mark[tmp] = 1;
            if( i%prime[j] == 0 )
            {
                mu[tmp] = 0;
                break;
            }
            
            mu[tmp] = mu[i]*-1;
        }
    }
//    for(int i=1;i<N;i++)
//        sum[i] += sum[i-1]+mu[i];
}



//long long gaobili(int b,int d)
//{
//    if(b<=0||d<=0) return 0;
//    int m = min(b,d);
//    long long ans = 0;
//    while(m>=1)
//    {
//        int tb = b/( b/m +1 )+1;
//        int td = d/( d/m +1 )+1;
//        //前进的最大位置
//        int tm = max(tb,td);
//        ans += (long long)(sum[m]-sum[tm-1])*(b/m)*(d/m);
//        m = tm-1;
//    }
//    return ans;
//}

 

代码量超少的求一些特别情况的mobus,复杂度O( nlog(n) )

  for (int i = 1; i <= n; i++)
      g[i] = f[i];
  for (int i = 1; i <= n; i++)
      for (int j = i + i; j <= n; j += i)
          g[j] -= g[i];

 

posted @ 2016-07-06 10:40  chenhuan001  阅读(197)  评论(0编辑  收藏  举报