zoukankan      html  css  js  c++  java
  • 太阳神

    【问题描述】
    太阳神拉很喜欢最小公倍数,有一天他想到了一个关于最小公倍数的题目。
    求满足如下条件的数对(a,b)对数:a,b均为正整数且a,b<=n而lcm(a,b)>n。其中的lcm当然表示最小公倍数。答案对1,000,000,007取模

    【输入格式】
    第一行一个正整数n。
    【输出格式】
    一行一个整数表示答案,对1,000,000,007取模。

    【样例输入输出】
    ra.in
    3
    ra.out
    2

    【数据范围与约定】
    对于20%的数据n<=2000;
    对于40%的数据n<=10000000;
    对于60%的数据n<=100000000;
    对于80%的数据n<=1000000000;
    对于100%的数据n<=10000000000

    分析:

    以下内容是搬运+整理

    受“序列计数”的启发,用一个小小的容斥,

    用n^2减去lcm(a,b)<=n的对数

    我们枚举d=gcd(a,b),令a’=a/d,b’=b/d;

    a=a’d,
    b=b’d
    lcm(a,b)=a’d*b’d/d=a’b’d<=n

    即我们要求的是
    gcd(a’,b’)=1 //不然gcd(a,b)!=d
    且a’b’d<=n的三元组(a’,b’,d)个数
    这里写图片描述
    反演一下:
    这里写图片描述
    美化一下
    这里写图片描述
    这里i是小于等于n^0.5的,因此我们可以线筛出μ函数的值
    现在问题在于如何求满足abc<=m的三元组个数
    我们可以限定a<=b<=c,先计算满足这个条件的三元组个数
    显然a可以在m^(1/3)的范围内枚举,
    b可以在(m/a)^0.5的范围内枚举,
    c的个数可以直接O(1)计算

    总的时间复杂度O(n^(2/3))

    这里写代码片
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #define ll long long
    
    using namespace std;
    
    const int mod=1000000007;
    const int N=100005;
    int n,ans=0;
    int sshu[N],tot=0,mu[N];
    bool no[N];
    
    void doit()
    {
        int i;
        memset(no,0,sizeof(no));
        mu[1]=1;
        for (i=2;i<=N;i++)
        {
            if (!no[i])
            {
                mu[i]=-1;  //素数 
                sshu[++tot]=i;
            }
            for (int j=1;j<=tot&&sshu[j]*i<=N;j++)
            {
                no[i*sshu[j]]=1; 
                if (i%sshu[j]==0)
                {
                    mu[i*sshu[j]]=0;  //含平方因子 
                    break;
                }
                mu[i*sshu[j]]=-mu[i];  //积性函数 
            }
        }
        int unit=trunc(sqrt(n));
        for (int i=1;i<=unit;i++)
        {
            int cnt;
            if (!mu[i]) continue;
            ll x=n/(1ll*i*i);
            cnt=0;
            for (int a=1;(ll)1ll*a*a*a<=x;a++)
            {
                int lb=trunc(sqrt(x/a));
                cnt-=2; cnt%=mod; cnt+=mod; cnt%=mod;
            }
            int la=trunc(sqrt(x));
            for (int a=1;a<=la;a++)
                cnt=(cnt-(x/1ll*a*a)*3%mod)%mod,cnt%=mod,cnt+=mod,cnt%=mod;
            ans=(ans+cnt*1ll*(n%mod)*(n%mod)%mod+mod)%mod;
        }
        ans=(((n%mod)*(n%mod)%mod-ans)%mod+mod)%mod;
    }
    
    int main()
    {
        //freopen("ra.in","r",stdin);  
        //freopen("ra.out","w",stdout);
        scanf("%d",&n);
        doit();
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    playbook配置不同系统版本的yum源配置
    playbook部署lamp
    lamp分离部署
    容器的介绍
    ansible 角色的使用
    playbook配置不同系统版本的yum源配置
    Ansible playbook 部署lamp
    Lamp 分离部署
    Ansible常用模块
    Ansible部署
  • 原文地址:https://www.cnblogs.com/wutongtong3117/p/7673485.html
Copyright © 2011-2022 走看看