zoukankan      html  css  js  c++  java
  • BZOJ 3309 莫比乌斯反演

    题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=3309

    题意:定义f(n)为n所含质因子的最大幂指数,求 $Ans=sum _{i=1}^{a}sum_{j=i}^{b}f(gcd(i,j))$

    T<=10000

    1<=a,b<=10^7

    解析:考虑a<b 

    枚举最大公约数d,得到:

    $$Ans=sum_{d=1}^a f(d)sum_{i=1}^{lfloorfrac{a}{d} floor}sum_{j=1}^{lfloorfrac{b}{d} floor}[gcd(i,j)=1]$$

    右边就是求$iin[1,{lfloorfrac{a}{d} floor}],jin[1,{lfloorfrac{b}{d} floor}]$ gcd(i,j)==1 的对数,根据莫比乌斯反演可以得到

    $$Ans=sum_{d=1}^a{f(d)}sum_{d'=1}^{lfloorfrac{a}{d} floor}mu(d'){lfloorfrac{a}{dd'} floor}{lfloorfrac{b}{dd'} floor}$$

    令 T=dd'

    $$Ans=sum_{T=1}^{a}{lfloorfrac{a}{T} floor}{lfloorfrac{b}{T} floor}sum_{d|T}mu(frac{T}{d}){f(d)}$$

    左边可以分块求出来,所以右边要预处理出来前缀和,但是nlog(n) 的复杂度会超时,所以要大力分析一波

    考虑  $G(n)=sum_{d|n}mu(frac{n}{d}){f(d)}$ ,只有当 n/d是互不相等的素数乘积的形式 才会产生贡献,其余都是0 ,

    设 n=p1^q1*p2^q2*p3^q3...pi^qi ,  k=max{qi},  f(d) 的取值只有两种 k 或 k-1

    考虑 n/d 的组合情况 令,qi=k 的p集合为 A  剩余p集合为 B  当A集合全部都取时 f(d) = k-1 其余情况f(d) = k 

    1.当B不为空的时候 B集合的组合情况是奇数,偶数各占一半的。所以集合A 中的每一种情况与B组合 也是奇偶数量相同,相互抵消了,G(n)=0。

    2.当B为空的时候,也就是所有的qi是相同的都等于k,因为只有当A集合全部都取时 f(d) = k-1 ,假设A集合的大小为m,一共有2^m个组合方案:

    1)m为奇数时 $mu(frac{n}{d})$ 是 负的 ,f(d)= k 的组合方案数就是偶数多一个 G(n)=k-(k-1)=1

    2)  m为偶数时 $mu(frac{n}{d})$ 是 正的 ,f(d)= k 的组合方案数就是奇数多一个 G(n)=(k-1)-k=-1

    总结一下就是:

    当n的素因子个数为偶数且素因子的幂次都相等时 G(n)=-1,

    当n的素因子个数为奇数且素因子的幂次都相等时 G(n)=-1,

    其余G(n)=0。

    对于幂次等于1的情况我们可以线性筛求出来G(i),G(i^k) =G(i)  指数级别的增长 O(n) 可以求出来所有的。

    AC代码

    #include <bits/stdc++.h>
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define all(a) (a).begin(), (a).end()
    #define fillchar(a, x) memset(a, x, sizeof(a))
    #define huan printf("
    ");
    #define debug(a,b) cout<<a<<" "<<b<<" ";
    using namespace std;
    const int maxn=1e7+10,inf=0x3f3f3f3f;
    typedef long long ll;
    const ll mod = 1000000007;
    typedef pair<int,int> pii;
    int check[maxn],prime[maxn],G[maxn],sum[maxn];
    void Mobius(int N)//线性筛求G(i)
    {
        int pos=0;G[1]=0;
        for (int i = 2 ; i <= N ; i++)
        {
            if (!check[i])
                prime[pos++] = i,G[i]=1;
            for (int j = 0 ; j < pos && i*prime[j] <= N ; j++)
            {
                check[i*prime[j]] = 1;
                if (i % prime[j] == 0)
                {
                    G[i*prime[j]]=0;
                    break;
                }
                G[i*prime[j]]=-G[i];
            }
        }
    }
    int main()
    {
        Mobius(1e7);
        sum[0]=sum[1]=0;
        for(int i=2;i<=1e7;i++)   //求G(i^k)
        {
            if(G[i]!=0)
                for(ll j=i;j<=1e7;j*=i)
                    sum[j]=G[i];
            sum[i]+=sum[i-1];  //前缀和
        }
        int t,n,m;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&m);
            if(n>m)swap(n,m);
            ll ans=0;
            for(int i=1,j;i<=n;i=j+1) // 分块sqrt复杂度求出答案
            {
                j=min(n/(n/i),m/(m/i));
                ans+=1ll*(sum[j]-sum[i-1])*(n/i)*(m/i);
            }
            printf("%lld
    ",ans);
        }
    }

      

  • 相关阅读:
    .net注册iis
    hdu 1081To The Max
    hdu 1312Red and Black
    hdu 1016Prime Ring Problem
    hdu 1159Common Subsequence
    hdu 1372Knight Moves
    hdu 1686Oulipo
    hdu 1241Oil Deposits
    hdu 1171Big Event in HDU
    hdu 4006The kth great number
  • 原文地址:https://www.cnblogs.com/stranger-/p/10744633.html
Copyright © 2011-2022 走看看