zoukankan      html  css  js  c++  java
  • 洛谷P3327 [SDOI2015]约数个数和——莫比乌斯反演

    约数个数和

    题目链接

    题解:

    思路:

    1.转换:将枚举i是x的倍数,j是y的倍数转换成枚举一个约数,有多少个数是其倍数,这样可以用整除分块预处理

    整除分块:

    给定n,求(Σd=1 ⌊n /d⌋)%998244353,n<=1e14

    直接枚举会爆

    考虑优化:

    我们发现,⌊n/d⌋是有可能等于⌊n/(d+1)⌋的

    那我们为什么要重复算呢? 直接加就好了!!

    那也就是说,对于一个i,我们要找到一个j,使得⌊n/i⌋=⌊n/(i+1)⌋=⌊n/(i+2)⌋=……=⌊n/j⌋!=n/(j+1)

    那么,我们得出 j=⌊n/(⌊n/i⌋)⌋

    于是就可以优化了,复杂度是O(sqrt(n))

    2.由莫比乌斯的重要性质,将gcd(a,b)=k转换成gcd(a,b)/k=1,令n等于[ gcd(a,b)/k=1 ],就可以把左边的式子代入化简,最后变成求莫比乌斯函数的前缀和

    3.流程:对后面两个sigma进行整除分块,每次累加预处理的u函数和f数组(整除分块)

    #include<bits/stdc++.h>
    using namespace std;
    #define N 50005
    #define ll long long
    ll pri[N],mu[N],sum[N],f[N],cnt=0,su[N];
    void suu()
    {
        mu[1]=1;
        int nn=N-5;
        for(int i=2;i<=nn;i++){
            if(!pri[i]) su[++cnt]=i,mu[i]=-1;
            for(int j=1;j<=cnt&&su[j]*i<=nn;j++){
                pri[su[j]*i]=1;
                if(i%su[j]) mu[su[j]*i]=-mu[i];
                else break;//mu=0
            }
        }
        for(int i=1;i<=nn;i++){//sqrt(n)的预处理 f[i]表示1~i中floor(p/i)的和 
            for(int l=1,r;l<=i;l=r+1){//枚举l和r 相当于整除分块里面的i和j 因为f会重复算 就直接算出重复的区间 用值来*上即可 
                 r=i/(i/l);
                 f[i]+=(r-l+1)*(i/l);
             }
         sum[i]=sum[i-1]+mu[i];//求一个莫比乌斯的函数前缀和 
        }
         
    }
    ll solve(int a,int b)
    {
        if(a>b) swap(a,b);
        ll ans=0;
        for(ll l=1,r;l<=a;l=r+1){//还要再一次整除分块 是后面那个枚举约数的式子 
            r=min(a/(a/l),b/(b/l));//一定要记得取min 因为r跳的是值更小的那一个!!!
            ans+=(sum[r]-sum[l-1])*f[a/l]*f[b/l];//推出来的式子 
        }
        return ans;
    }
    int main()
    {
        freopen("c.in","r",stdin);
        freopen("c.out","w",stdout);
        int T;
        suu();
        scanf("%d",&T);
        while(T--){
            int n,m;
            scanf("%d%d",&n,&m);
            printf("%lld
    ",solve(n,m));
        }
    }
    /*
    2
    7 4
    5 6
    */
    View Code
  • 相关阅读:
    (15)如何使用Cocos2d-x 3.0制作基于tilemap的游戏:第三部分(完)
    (14)如何使用Cocos2d-x 3.0制作基于tilemap的游戏:第二部分
    (13)如何使用Cocos2d-x 3.0制作基于tilemap的游戏:第一部分
    (12)瓦片地图
    (11)粒子系统
    (10)场景转换(Transitions)
    (9)SpriteFrameCache和TextureCache
    LeetCode:数组中的第K个最大元素【215】
    LeetCode:累加数【306】
    LeetCode:组合总数III【216】
  • 原文地址:https://www.cnblogs.com/mowanying/p/11272966.html
Copyright © 2011-2022 走看看