• P2568 莫比乌斯反演+整除分块


    #include<bits/stdc++.h>
    #define LL long long
    using namespace std;
    const int maxn=1e7+10;
    bool vis[maxn];
    int prime[maxn];
    int mu[maxn];
    int sum1[maxn];
    int sum2[maxn];
    int tot=0;
    void get_mu()// mo bi su si han shu
    {
        mu[1]=1;  vis[1]=1;
        for(int i=2;i<maxn;i++)  // prime = 0;  other = 1;
        {
            if(!vis[i]){ prime[++tot]=i; mu[i]=-1;}
            for(int j=1;j<=tot&& prime[j]*i<maxn;j++)
            {
                vis[prime[j]*i]=1;
                if(i%prime[j]==0)break;
                mu[i*prime[j]]=-mu[i];
            }
        }
        for(int i=1;i<=tot;i++)
        {
            for(int j=prime[i];j<maxn;j+=prime[i])
            {
                sum1[j]+=mu[j/prime[i]];
            }
        }
        //for(int i=1;i<maxn;i++)  sum2[i]=sum2[i-1]+sum1[i];
    }
    int main()
    {
        get_mu();
        int n; cin>>n;
        LL ans=0;
        for(int i=1;i<=n;i++)
        {
            ans+=1LL*(n/i)*(n/i)*sum1[i];
        }
        cout<<ans<<endl;
    }
    过度代码

    整除分块  (看起来更麻烦)

    #include<bits/stdc++.h>
    #define LL long long
    using namespace std;
    const int maxn=1e7+10;
    bool vis[maxn];
    int prime[maxn];
    int mu[maxn];
    int sum1[maxn];
    int sum2[maxn];
    int tot=0;
    void get_mu()// mo bi su si han shu
    {
        mu[1]=1;  vis[1]=1;
        for(int i=2;i<maxn;i++)  // prime = 0;  other = 1;
        {
            if(!vis[i]){ prime[++tot]=i; mu[i]=-1;}
            for(int j=1;j<=tot&& prime[j]*i<maxn;j++)
            {
                vis[prime[j]*i]=1;
                if(i%prime[j]==0)break;
                mu[i*prime[j]]=-mu[i];
            }
        }
        for(int i=1;i<=tot;i++)
        {
            for(int j=prime[i];j<maxn;j+=prime[i])
            {
                sum1[j]+=mu[j/prime[i]];
            }
        }
        for(int i=1;i<maxn;i++)  sum2[i]=sum2[i-1]+sum1[i];
    }
    int main()
    {
        get_mu();
        int n; cin>>n;
        LL ans=0;
        //for(int i=1;i<=n;i++)  ans+=1LL*(n/i)*(n/i)*sum1[i];
        for(int l=1,r;l<=n;l=r+1)
        {
            r=n/(n/l);  //  l-r 区间相同值  区间值n/l
            ans+=1LL*(n/l)*(n/l)*(sum2[r]-sum2[l-1]);
        }
        cout<<ans<<endl;
    }
  • 相关阅读:
    HDU 3586 Information Disturbing (树形DP+二分)
    HDU 6053 TrickGCD (莫比乌斯函数)
    51Nod 1554 欧姆诺姆和项链 (KMP)
    HDU 6153 A Secret (KMP)
    HDU 6156 Palindrome Function (数位DP)
    HDU 6148 Valley Numer (数位DP)
    UVa 1513 Movie collection (树状数组)
    HDU 6125 Free from square (状压DP+背包)
    UVa 10766 Organising the Organisation (生成树计数)
    tensorflow 待阅读的资料
  • 原文地址:https://www.cnblogs.com/Andromeda-Galaxy/p/10700602.html
Copyright © 2020-2023  润新知