zoukankan      html  css  js  c++  java
  • [学习笔记]莫比乌斯反演

    1、(Crash)的数字表格

    (assume n<m)

    (sum_{i=1}^{n}sum_{j=1}^{m}lcm(i,j))

    (sum_{d=1}^{n}sum_{i=1}^{n}sum_{j=1}^{m}[gcd(i,j)==d]frac{ij}{d})

    (sum_{d=1}^{n}dsum_{i=1}^{n/d}sum_{j=1}^{m/d}[gcd(i,j)==1]ij)

    (sum_{d=1}^{n}dsum_{i=1}^{n/d}sum_{j=1}^{m/d}sum_{x|gcd(i,j)}mu(x)ij)

    (sum_{d=1}^{n}dsum_{i=1}^{n/d}sum_{j=1}^{m/d}sum_{x|i,x|j}mu(x)ij)

    (sum_{x=1}^{n}sum_{d=1}^{n}dsum_{i=1}^{n/d}sum_{j=1}^{m/d}mu(x)ij[x|i,x|j])

    (assume i=ix,j=jx)

    (sum_{x=1}^{n}mu(x)x^{2}sum_{d=1}^{n}dsum_{i=1}^{frac{n}{dx}}sum_{j=1}^{frac{m}{dx}}ij)

    (g(x)=sum_{i=1}^{frac{n}{dx}}sum_{j=1}^{frac{n}{dx}}ij=[frac{frac{n}{dx}(frac{n}{dx}+1)}{2}]^{2})

    (sum_{d=1}^{n}dsum_{x=1}^{n/d}mu(x)x^{2}g(x))

    用数论分块优化(O(nsqrt{n}))

    记得开(O_{2})

    (Code Below:)

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn=10000000+10;
    const int p=20101009;
    ll n,m,prim[maxn],vis[maxn],mu[maxn],sum[maxn],cnt,ans;
    ll a,b,d;
    
    void getmu(ll n){
    	mu[1]=1;
    	register ll i,j;
    	for(i=2;i<=n;i++){
    		if(!vis[i]){prim[++cnt]=i;mu[i]=-1;}
    		for(j=1;i*prim[j]<=n&&j<=cnt;j++){
    			vis[i*prim[j]]=1;
    			if(i%prim[j]==0) break;
    			mu[i*prim[j]]=-mu[i];
    		}
    	}
    	for(i=1;i<=n;i++) sum[i]=(sum[i-1]+mu[i]*i*i%p)%p;
    }
    
    ll g(ll x){
    	return ((a/x)*(a/x+1)/2%p)*((b/x)*(b/x+1)/2%p)%p;
    }
    
    int main()
    {
    	scanf("%lld%lld",&n,&m);
    	if(n>m) swap(n,m);
    	getmu(n);
    	register ll l,r,num;
    	for(d=1;d<=n;d++){
    		num=0;a=n/d;b=m/d;
    		for(l=1;l<=a;l=r+1){
    			r=min(a/(a/l),b/(b/l));
    			num=(num+(sum[r]-sum[l-1])*g(l)%p)%p;
    		}
    		ans=(ans+d*num%p)%p;
    	}
    	printf("%lld
    ",(ans+p)%p);
        return 0;
    }
    

    2、简单的数学题

    (sum_{i=1}^{n}sum_{j=1}^{n}ijgcd(i,j))

    (sum_{d=1}^{n}dsum_{i=1}^{n}sum_{j=1}^{n}[gcd(i,j)==d]ij)

    (sum_{d=1}^{n}d^{3}sum_{i=1}^{n/d}sum_{j=1}^{n/d}[gcd(i,j)==1]ij)

    (sum_{d=1}^{n}d^{3}sum_{i=1}^{n/d}sum_{j=1}^{n/d}sum_{x|gcd(i,j)}mu(x)ij)

    (sum_{d=1}^{n}d^{3}sum_{i=1}^{n/d}sum_{j=1}^{n/d}sum_{x=1}^{n/d}mu(x)[x|i,x|j]ij)

    (assume i=ix,j=jx)

    (sum_{d=1}^{n}d^{3}sum_{x=1}^{n/d}mu(x)x^{2}sum_{i=1}^{frac{n}{dx}}sum_{j=1}^{frac{n}{dx}}ij)

    (g(x)=sum_{i=1}^{frac{n}{dx}}sum_{j=1}^{frac{n}{dx}}ij=[frac{frac{n}{dx}(frac{n}{dx}+1)}{2}]^{2})

    (sum_{d=1}^{n}d^{3}sum_{x=1}^{n/d}mu(x)x^{2}g(x))

    突然发现时间复杂度(O(nsqrt{n})),解法是伪的

    所以(mobius)函数没用了,要用(phi)函数

    (sum_{i=1}^{n}sum_{j=1}^{n}ijgcd(i,j))

    (sum_{i=1}^{n}sum_{j=1}^{n}ijsum_{k|i,k|j}varphi(k))

    (sum_{k=1}^{n}varphi(k)sum_{k|i}sum_{k|j}ij)

    (sum_{k=1}^{n}varphi(k)sum_{i=1}^{n}sum_{j=1}^{n}[k|i,k|j]ij)

    (sum_{k=1}^{n}varphi(k)k^{2}sum_{i=1}^{n/k}sum_{j=1}^{n/k}ij)

    (g(x)=(sum_{i=1}^{x}i)^{2}=[frac{x(x+1)}{2}]^{2})

    (sum_{k=1}^{n}varphi(k)k^{2}g(n/k)^{2})

    #include <bits/stdc++.h>
    #define ll long long
    #define res register ll
    using namespace std;
    const int maxn=7500000+10;
    ll p,n,prim[maxn],vis[maxn],phi[maxn],cnt,ans,inv2,inv6;
    map<ll,ll> Phi;
    
    ll fast_pow(ll a,ll b){
    	ll ret=1;
    	for(;b;b>>=1,a=a*a%p)
    		ret=ret*(b&1?a:1)%p;
    	return ret;
    }
    
    void getphi(ll n){
    	phi[1]=1;
    	res i,j;
    	for(i=2;i<=n;i++){
    		if(!vis[i]){prim[++cnt]=i;phi[i]=i-1;}
    		for(j=1;i*prim[j]<=n&&j<=cnt;j++){
    			vis[i*prim[j]]=1;
    			if(i%prim[j]==0){
    				phi[i*prim[j]]=phi[i]*prim[j]%p;
    				break;
    			}
    			phi[i*prim[j]]=phi[i]*(prim[j]-1)%p;
    		}
    	}
    	for(i=1;i<=n;i++) phi[i]=(i*i%p*phi[i]%p+phi[i-1])%p;
    }
    
    ll g(ll x){
    	x%=p;
    	return (x*(x+1)/2%p)*(x*(x+1)/2%p)%p;
    }
    
    ll f(ll x){
    	x%=p;
    	return x*(x+1)%p*(2*x+1)%p*inv6%p;
    }
    
    
    ll calc_phi(res n){
    	if(n<=7500000) return phi[n];
    	if(Phi[n]) return Phi[n];
    	res ans=g(n);
    	for(res l=2,r;l<=n;l=r+1){
    		r=n/(n/l);
    		ans=(ans-(f(r)-f(l-1)+p)%p*calc_phi(n/l)%p)%p;
    	}
    	return Phi[n]=(ans+p)%p;
    }
    
    int main()
    {
    	scanf("%lld%lld",&p,&n);
    	getphi(7500000);
    	inv2=fast_pow(2,p-2);
    	inv6=fast_pow(6,p-2);
    	for(res l=1,r;l<=n;l=r+1){
    		r=n/(n/l);
    		ans=(ans+(calc_phi(r)-calc_phi(l-1)+p)%p*g(n/l)%p)%p;
    	}
    	printf("%lld
    ",(ans+p)%p);
    	return 0;
    }
    

    3、于神之怒加强版

    (assume n<m)

    (sum_{i=1}^{n}sum_{j=1}^{m}gcd(i,j)^{k})

    (sum_{d=1}^{n}d^{k}sum_{i=1}^{n}sum_{j=1}^{m}[gcd(i,j)==d])

    (sum_{d=1}^{n}d^{k}sum_{i=1}^{n/d}sum_{j=1}^{m/d}[gcd(i,j)==1])

    (sum_{d=1}^{n}d^{k}sum_{i=1}^{n/d}sum_{j=1}^{m/d}sum_{x|gcd(i,j)}mu(x))

    (sum_{d=1}^{n}d^{k}sum_{x=1}^{n}mu(x)sum_{i=1}^{n/d}sum_{j=1}^{m/d}[x|i,x|j])

    (sum_{d=1}^{n}d^{k}sum_{x=1}^{n/d}mu(x)lfloorfrac{n}{dx} floorlfloorfrac{m}{dx} floor)

    (sum_{t=1}^{n}lfloorfrac{n}{t} floorlfloorfrac{m}{t} floorsum_{d|t}d^{k}mu(frac{t}{d}))

    (f(x)=sum_{d|t}d^{k}mu(frac{t}{d}))

    (sum_{t=1}^{n}f(t)lfloorfrac{n}{t} floorlfloorfrac{m}{t} floor)

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int maxn=5000000+10;
    const int p=1e9+7;
    ll n,m,k,prim[maxn],vis[maxn],f[maxn],cnt,ans;
    
    ll fast_pow(ll a,ll b){
    	ll ret=1;
    	for(;b;b>>=1,a=a*a%p)
    		ret=ret*(b&1?a:1)%p;
    	return ret;
    }
    
    void sieve(ll n){
    	f[1]=1;
    	ll i,j;
    	for(i=2;i<=n;i++){
    		if(!vis[i]){prim[++cnt]=i;f[i]=fast_pow(i,k)-1;}
    		for(j=1;i*prim[j]<=n&&j<=cnt;j++){
    			vis[i*prim[j]]=1;
    			if(i%prim[j]==0){
    				f[i*prim[j]]=f[i]*(f[prim[j]]+1)%p;
    				break;
    			}
    			f[i*prim[j]]=f[i]*f[prim[j]]%p;
    		}
    	}
    	for(i=1;i<=n;i++) f[i]=(f[i]+f[i-1])%p;
    }
    
    int main()
    {
    	ll T,l,r;
    	scanf("%lld%lld",&T,&k);
    	sieve(5000000);
    	while(T--){
    		scanf("%lld%lld",&n,&m);
    		if(n>m) swap(n,m);
    		ans=0;
    		for(l=1,r;l<=n;l=r+1){
    			r=min(n/(n/l),m/(m/l));
    			ans=(ans+(n/l)*(m/l)%p*(f[r]-f[l-1]+p)%p)%p;
    		}
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    如何在文本编辑器中实现搜索功能? 字符串比较算法 BF算法 RK算法
    怎么读源码 读源码的一些技巧
    系统性学习
    堆 二叉堆 找流的中位数
    apk系统签名小技巧
    常用adb命令总结
    Android6.0 源码修改之Setting列表配置项动态添加和静态添加
    AndroidStudio开发Java工程(解决java控制台中文打印乱码+导入jar包运行工程)
    加载loading对话框的功能(不退出沉浸式效果)
    Android6.0 源码修改之屏蔽导航栏虚拟按键(Home和RecentAPP)/动态显示和隐藏NavigationBar
  • 原文地址:https://www.cnblogs.com/owencodeisking/p/9826340.html
Copyright © 2011-2022 走看看