zoukankan      html  css  js  c++  java
  • 洛谷P2257 YY的GCD【莫比乌斯反演】

    传送门

    题解

    和前一道模板题类似,先设 (f(d)),再得 (F(n)),然后反演 (f(n))。因为最终答案:

    [Ans=sum_{nin prime}f(n)=sum_{nin prime}sum_{t=1}^{iglfloorfrac{N}{n}ig floor}mu(t)igglfloorfrac{N}{nt}igg floorigglfloorfrac{M}{nt}igg floor ]

    还可以继续处理,但这里我还有点想不明白,可以先枚举 (T=nt)

    [Ans=sum_{T=1}^{N}igglfloorfrac{N}{T}igg floorigglfloorfrac{M}{T}igg floorsum_{n|T,nin prime}mu(frac{T}{n}) ]

    后面那一坨就可以在求 (mu) 之后处理出来,然后算 (Ans),就与前一道模板题差不多了,预处理后面那一坨得前缀和,然后每次询问用整除分块计算。

    代码

    #include <iostream>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    using namespace std;
    typedef long long LL;
    const int N=1e7+10;
    int n,m,vis[N],prime[N],cnt,mu[N];
    LL sum[N];
    
    void euler(int n){
    	mu[1]=1;
    	for(int i=2;i<=n;i++){
    		if(!vis[i]) {prime[++cnt]=i;mu[i]=-1;}
    		for(int j=1;1ll*i*prime[j]<=n;j++){
    			vis[i*prime[j]]=1;
    			if(i%prime[j]==0) {mu[i*prime[j]]=0;break;}
    			mu[i*prime[j]]=-mu[i];
    		}
    	}
    	for(int i=1;i<=cnt;i++)
    		for(int j=1;1ll*j*prime[i]<=n;j++)
    			sum[j*prime[i]]+=mu[j];
    	for(int i=1;i<=n;i++) sum[i]+=sum[i-1];
    }
    
    int main(){
    	euler(1e7);
    	int T;scanf("%d",&T);
    	while(T--){
    		LL ans=0;
    		scanf("%d%d",&n,&m);
    		if(n>m) swap(n,m);
    		for(int l=1,r;l<=n;l=r+1){
    			r=min(n/(n/l),m/(m/l));
    			ans+=1ll*(sum[r]-sum[l-1])*(n/l)*(m/l);
    		}
    		printf("%lld
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    matplotlib formatters
    matplotlib locators
    mysql> 12 simple but staple commands
    mysql--> find your databases' local position
    ubuntu16.04安装caffe常见问题及其解决方案
    gitlab使用说明
    vim配置摘要
    shell 提示符个性化设置
    python拼接参数不确定的SQL时防注入问题--条件语句最后拼入
    python_opencv ——图片预处里(二)
  • 原文地址:https://www.cnblogs.com/BakaCirno/p/12523480.html
Copyright © 2011-2022 走看看