zoukankan      html  css  js  c++  java
  • 莫比乌斯反演呓语

    接下来介绍一种线性筛的做法来筛出莫比乌斯函数。 
    if (i % p[j] == 0)这句话非常关键,也是为什么这个筛法是线性筛的原因。 
    同样把这个程序的μ[x]μ[x] 去掉就是单纯的质数筛,同样这个质数筛由于if (i % p[j] == 0) 的存在,也是一个线性筛。

    void mobius()
    {
        int i,j; mbs[1] = 1;
        fo(i,2,N)
            {
                if (!vis[i]) {p[++p[0]] = i; mbs[i] = -1;}
                for (j = 1;j <= p[0] && i * p[j] <= N; j++)
                    {
                        vis[i*p[j]] = 1;
                        if (i % p[j] == 0) {mbs[i*p[j]] = 0; break;}
                        mbs[i*p[j]] = - mbs[i];
                    }
            }
    }
    

      

    #include <bits/stdc++.h>
    using namespace std;
    
    const int MAXN = 100000;
    bool check[MAXN+10];
    int prime[MAXN+10];
    int mu[MAXN+10];
    
    //求1-n,1-m内gcd=x(的倍数)的个数,修改可以改这个(大概,我还没试过)
    inline long long f(int n,int m,int x){
        return (n/x)*(m/x);
    }
    
    
    void Moblus()
    {
        memset(check,false,sizeof(check));
        mu[1] = 1;
        int tot = 0;
        for(int i = 2; i <= MAXN; i++)
        {
            if( !check[i] )
            {
                prime[tot++] = i;
                mu[i] = -1;
            }
            for(int j = 0; j < tot; j ++)
            {
                if( i * prime[j] > MAXN) break;
                check[i * prime[j]] = true;
                if( i % prime[j] == 0)
                {
                    mu[i * prime[j]] = 0;
                    break;
                }
                else
                {
                    mu[i * prime[j]] = -mu[i];
                }
            }
        }
    }
    int sum[MAXN+10];
    
    
    //找[1,n],[1,m]内互质的数的对数
    long long solve(int n,int m)
    {
        long long ans = 0;
        if(n > m)swap(n,m);
        for(int i = 1, la = 0; i <= n; i = la+1)
        {
            la = min(n/(n/i),m/(m/i));
            ans += (long long)(sum[la] - sum[i-1])*f(n,m,i);
        }
        return ans;
    
    }
    int main()
    {
        Moblus();
        sum[0] = 0;
        for(int i = 1; i <= MAXN; i++)   sum[i] = sum[i-1] + mu[i];
        int a,b,c,d,k;
        int T;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
            long long ans = solve(b/k,d/k) - solve((a-1)/k,d/k) - solve(b/k,(c-1)/k) + solve((a-1)/k,(c-1)/k);
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    Spring Boot 使用actuator监控与管理
    Spring Boot入门
    mysql中update语句的锁
    LinkedList深入学习
    23种设计模式学习之享元模式
    23种设计模式学习之桥接模式
    23种设计模式学习之外观模式
    23种设计模式学习之代理模式
    23种设计模式学习之装饰者模式
    23种设计模式学习之适配器模式
  • 原文地址:https://www.cnblogs.com/bestefforts/p/9473771.html
Copyright © 2011-2022 走看看