zoukankan      html  css  js  c++  java
  • [国家集训队]Crash的数字表格(莫比乌斯反演)

    这道题在bzoj有多组数据,那么洛谷题解里的双重分块在bzoj就会T

    那我就讲一下只有一重分块的做法

    时间复杂度(大概) O((N_{max}+Tsqrt{N_i})) 其中T为数据组数

    [sumlimits_{i=1}^nsumlimits_{j=1}^moperatorname{lcm(i,j)} ]

    [=sumlimits_{i=1}^nsumlimits_{j=1}^mfrac{icdot j}{gcd(i,j)} ]

    [=sumlimits_{i=1}^n sumlimits_{i=1}^m sumlimits_{d=1}^{min(n,m)}frac{icdot j}d[gcd(i,j)=d] ]

    [=sumlimits_{d=1}^{min(n,m)} sumlimits_{i=1}^{lfloorfrac{n}d floor} sumlimits_{i=1}^{lfloorfrac{m}d floor} dijcdot [gcd(i,j)=1] ]

    [=sumlimits_{d=1}^{min(n,m)} sumlimits_{i=1}^{lfloorfrac{n}d floor} sumlimits_{i=1}^{lfloorfrac{m}d floor} dij sumlimits_{x|gcd(i,j)}^{}μ(x) ]

    [=sumlimits_{d=1}^{min(n,m)} sumlimits_{i=1}^{lfloorfrac{n}d floor} sumlimits_{i=1}^{lfloorfrac{m}d floor} dij sumlimits_{x|i,x|j}μ(x) ]

    然后把μ(x)和d调到前面去,i变成ix,j变成jx

    [=sumlimits_{d=1}^{min(n,m)}d sumlimits_{x=1}^{min(lfloorfrac{n}d floor,lfloorfrac{m}d floor)}μ(x) sumlimits_{i=1}^{lfloorfrac{n}{dx} floor}ix sumlimits_{j=1}^{lfloorfrac{m}{dx} floor}jx ]

    然后把x也调到前面去

    [=sumlimits_{d=1}^{min(n,m)}d sumlimits_{x=1}^{min(lfloorfrac{n}d floor,lfloorfrac{m}d floor)}x^2μ(x) sumlimits_{i=1}^{lfloorfrac{n}{dx} floor} sumlimits_{j=1}^{lfloorfrac{m}{dx} floor}ij ]

    然后等差数列

    [=sumlimits_{d=1}^{min(n,m)}d sumlimits_{x=1}^{min(lfloorfrac{n}d floor,lfloorfrac{m}d floor)}x^2mu(x) frac{(1+lfloorfrac{n}{dx} floor)lfloorfrac{n}{dx} floor}{2}frac{(1+lfloorfrac{m}{dx} floor)lfloorfrac{m}{dx} floor}{2} ]

    在洛谷的话推到这一步就够了

    但是想要在bzoj过这道题还要接着优化

    然后设T=dx,所以x=(frac{T}{d})

    [=sumlimits_{T=1}^{min(n,m)} frac{(1+lfloorfrac{n}{T} floor)lfloorfrac{n}{T} floor}{2}frac{(1+lfloorfrac{m}{T} floor)lfloorfrac{m}{T} floor}{2} sumlimits_{d|T}dfrac{T^2}{d^2}mu(frac{T}{d}) ]

    由于对称性

    [=sumlimits_{T=1}^{min(n,m)} frac{(1+lfloorfrac{n}{T} floor)lfloorfrac{n}{T} floor}{2}frac{(1+lfloorfrac{m}{T} floor)lfloorfrac{m}{T} floor}{2} sumlimits_{d|T}frac{T}{d}d^2mu({d}) ]

    [=sumlimits_{T=1}^{min(n,m)} frac{(1+lfloorfrac{n}{T} floor)lfloorfrac{n}{T} floor}{2}frac{(1+lfloorfrac{m}{T} floor)lfloorfrac{m}{T} floor}{2} sumlimits_{d|T}Tdmu({d}) ]

    然后我们设

    [g(T)=sumlimits_{d|T}Tdmu({d}) ]

    然后可以发现g是一个积性函数

    所以有

    [g(Pi P_i^{ai})=Pi g(P_i^{ai}) ]

    [=Pi (T*P_i^{0}*mu(1)+T*P_i*mu(1)) ]

    [=Pi (T-T*P_i) ]

    [=Pi (T*(1-P_i)) ]

    因此

    [g(p)=1-p ]

    [g(p^k)=g(p^{k-1}) ]

    当np互质时,有

    [g(np)=g(n)*g(p) ]

    然后筛一筛就出来了

    代码:

    #pragma GCC optimize(3)
    #include<bits/stdc++.h>
    #define int long long
    #define N 10000010
    using namespace std;
    const int mod=20101009;
    int vis[N],prim[N/10],mu[N],low[N],sum[N],cnt;
    void pre(int n){
    	mu[1]=1;
    	sum[1]=low[1]=1;
    	for(int i=2;i<=n;i++){
    		if(!vis[i])mu[i]=-1,prim[++cnt]=i,low[i]=i,sum[i]=(1-i+mod)%mod;
    		for(int j=1;j<=cnt&&i*prim[j]<=n;j++){
    			vis[i*prim[j]]=1;
    			if(i%prim[j]==0){
    				low[i*prim[j]]=low[i]*prim[j];
    				if(low[i]==i)sum[i*prim[j]]=sum[i];
    				else sum[i*prim[j]]=sum[i/low[i]]*sum[prim[j]*low[i]]%mod;
    				break;
    			}else{
    				low[i*prim[j]]=prim[j];
    				sum[i*prim[j]]=sum[i]*sum[prim[j]]%mod;
    				mu[i*prim[j]]=-mu[i];
    			}
    		}
    	}
    	for(int T=1;T<=n;T++)sum[T]=(T*sum[T]%mod+sum[T-1])%mod;
    }
    int ask(int x,int y){return (x+y)*(y-x+1)/2%mod;}
    int query(int n,int m){
    	int re=0;
    	int mx=min(n,m);
    	for(int l=1,r;l<=mx;l=r+1){
    		r=min(n/(n/l),m/(m/l));
    		int tmp=ask(1,n/l)*ask(1,m/l)%mod;
    		tmp=tmp*(sum[r]-sum[l-1]+mod)%mod;
    		re=(re+tmp)%mod;
    	}
    	return re;
    }
    int t;
    signed main(){
    	pre(10000000);
    	int n,m;
    	scanf("%lld%lld",&n,&m);
    	printf("%lld
    ",query(n,m));
    	return 0;
    }
    
  • 相关阅读:
    Windows下git使用代理服务器的设置方法
    SQL backup&restore
    css3 随记
    HTML5 上传图片预览
    jQuery.event.move
    css3 html5 手机设备 列表的弹回和加速移动
    16进制与utf-8
    android 使用现成做get请求
    android 往sd卡中写入文件
    android 遍历控件
  • 原文地址:https://www.cnblogs.com/nlKOG/p/10543409.html
Copyright © 2011-2022 走看看