• [模板]莫比乌斯反演


    前置技能:整除分块

    计算形如$sumlimits_{i=1}^{n}a_if(lfloorfrac{n}{i} floor)$的式子

    可以发现$lfloorfrac{n}{i} floor$只有$O(sqrt{n})$种取值,且相同的取值的i是连续的,所以可以$O(sqrt{n})$来求

    需要能快速求出$a_i$的前缀和(配合各种筛)

    和i相同的的最后一个位置,是$n/(n/i)$

    例:$sum{mu(i)frac{n}{i}frac{m}{i}}$

    inline int calc(int n,int m){
        if(n>m) swap(n,m);
        int i=1,pos=1,re=0;
        for(;i<=n;i=pos+1){
            pos=min(n/(n/i),m/(m/i));
            re+=(mu[pos]-mu[i-1])*(n/i)*(m/i);
        }return re;
    }
    View Code

    莫比乌斯函数$mu$

    定义:

      当x有次数>=2的质因子时,$mu(x)=0$

      否则,设k为x的质因子数量,$mu(x)=(-1)^k$

      特殊地,$mu(1)=1$ (其实也不特殊..)

    $mu$是积性函数,可以线性筛出。有时也可以作为容斥系数

    有$sumlimits_{d|n}mu(d)=[n=1]$,可用二项式定理证明

    莫比乌斯反演

    已知数论函数$F(n)$且$F(n)=sum_{d|n}f(d)$

    则有$f(n)=sumlimits_{d|n}mu(d)F(frac{n}{d})$

    以及另一种形式(d是n的倍数):

    $F(n)=sumlimits_{n|d}f(d)$

    $f(n)=sumlimits_{n|d}mu(frac{d}{n})F(d)$

    具体应用时,需要构造想求的f和好求的F

    例题

    luogu2155 YY的GCD ,做法先参见http://www.cnblogs.com/peng-ym/p/8652288.html

     1 #include<bits/stdc++.h>
     2 #define CLR(a,x) memset(a,x,sizeof(a))
     3 #define MP make_pair
     4 using namespace std;
     5 typedef long long ll;
     6 typedef unsigned long long ull;
     7 typedef pair<int,int> pa;
     8 const int maxn=1e7+10;
     9 
    10 inline ll rd(){
    11     ll x=0;char c=getchar();int neg=1;
    12     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
    13     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    14     return x*neg;
    15 }
    16 
    17 int g[maxn],pri[maxn],cnt,T,mu[maxn];
    18 bool np[maxn];
    19 
    20 inline ll calc(int n,int m){
    21     if(n>m) swap(n,m);
    22     ll re=0;
    23     for(int i=1,pos;i<=n;i=pos+1){
    24         pos=min(n/(n/i),m/(m/i));
    25         re+=1ll*(n/i)*(m/i)*(g[pos]-g[i-1]);
    26     }return re;
    27 }
    28 
    29 int main(){
    30     //freopen("","r",stdin);
    31     int i,j,k;
    32     g[1]=0;np[1]=1;mu[1]=1;
    33     for(i=2;i<=1e7;i++){
    34         if(!np[i]){
    35             pri[++cnt]=i;
    36             g[i]=1;mu[i]=-1;
    37         }
    38         for(j=1;j<=cnt&&pri[j]*i<=1e7;j++){
    39             np[i*pri[j]]=1;
    40             if(i%pri[j]==0){
    41                 g[i*pri[j]]=mu[i];break;
    42             }
    43             g[i*pri[j]]=mu[i]-g[i];
    44             mu[i*pri[j]]=mu[i]*mu[pri[j]];
    45         }
    46     }
    47     for(i=1;i<=1e7;i++) g[i]+=g[i-1];
    48     for(T=rd();T;T--){
    49         printf("%lld
    ",calc(rd(),rd()));
    50     }
    51     return 0;
    52 }
    View Code
  • 相关阅读:
    tkinter中entry输入控件(四)
    tkinter中button按钮控件(三)
    tkinter中lable标签控件(二)
    tkinter简介(一)
    selenium中的xpath定位
    python实现邮件的发送
    python发送手机动态验证码
    selenium提供的截图功能
    selenium中浏览器及对应的驱动(可下载)
    PHP实现微信提现功能
  • 原文地址:https://www.cnblogs.com/Ressed/p/10226687.html
Copyright © 2020-2023  润新知