zoukankan      html  css  js  c++  java
  • BZOJ3994:[SDOI2015]约数个数和——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=3994

    https://www.luogu.org/problemnew/show/P3327#sub

    参考:https://blog.csdn.net/zmoiynlp/article/details/45176129

    (他的公式好像最后一点有些问题)

    请先锻炼好抗打击能力再做这道题,可以看我的模板:数论函数 & 莫比乌斯反演

    我们有(d(ij)=sum_{k|i}sum_{l|j}[gcd(k,l)==1])

    (感性证明很简单,于是就不证了)

    (这个是本题第一难的地方,信息数学竞赛

    (sum_{i=1}^nsum_{j=1}^md(ij))

    (=sum_{i=1}^nsum_{j=1}^msum_{k|i}sum_{l|j}[gcd(k,l)=1])

    (=sum_{k=1}^nsum_{l=1}^mlfloorfrac{n}{k} floorlfloorfrac{m}{l} floor[gcd(k,l)=1])(跳了步,希望大家看得懂)

    (=)套路(实则是跳步)

    (=sum_{d=1}^{min(n,m)}mu(d)sum_{k=1}^{n}sum_{l=1}^{m}lfloorfrac{n}{k} floorlfloorfrac{m}{l} floor[k|d][l|d])

    (=sum_{d=1}^{min(n,m)}mu(d)sum_{k=1}^{lfloorfrac{n}{d} floor}sum_{l=1}^{lfloorfrac{m}{d} floor}lfloorfrac{n} {kd} floorlfloorfrac{m}{ld} floor)

    我们令(g(n)=sum_{i=1}^nlfloorfrac{n}{i} floor)

    我们的套路有(sum_{i=1}^nsum_{j=1}^n[i|j]=g(n))

    是的你没有看错这玩意就是约数函数的前缀和。

    (如果你还没看出来的话,把两个sigma颠倒一下)

    (这是本题第二难的地方,信息数学竞赛

    于是预处理约数函数的前缀和。

    (用到了算数基本定理的推导和约数函数是积性函数的性质,可见https://blog.csdn.net/ControlBear/article/details/77527115

    (emmm……就算你全推出来了,这个不会也白搭,信息数学竞赛

    (我为什么要去作死做信息数学竞赛题啊!)

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N=5e4+5;
    inline int read(){int x;scanf("%d",&x);return x;}
    ll su[N],miu[N],d[N],c[N];
    int he[N];
    void init(int n){
    	int tot=0;
    	miu[1]=d[1]=c[1]=1;
    	for(int i=2;i<=n;i++){
    		if(!he[i]){
    			su[++tot]=i;
    			miu[i]=-1;
    			c[i]=1;d[i]=2;
    		}
    		for(int j=1;j<=tot;j++){
    			if(i*su[j]>n)break;
    			he[i*su[j]]=1;
    			if(i%su[j]==0){
    				miu[i*su[j]]=0;
    				d[i*su[j]]=d[i]/(c[i]+1)*(c[i]+2);
    				c[i*su[j]]=c[i]+1;
    				break;
    			}else{
    				miu[i*su[j]]=miu[i]*miu[su[j]];
    				d[i*su[j]]=d[i]*d[su[j]];
    				c[i*su[j]]=1;	
    			}
    		}
    	}
    	for(int i=1;i<=n;i++){
    		miu[i]+=miu[i-1];
    		d[i]+=d[i-1];
    	}
    }
    int main(){
    	init(5e4);
    	int t=read();
    	while(t--){
    		ll n=read(),m=read();
    		ll ans=0;
    		for(ll i=1,j;i<=min(n,m);i=j+1){
    			j=min(n/(n/i),m/(m/i));
    			ans+=(miu[j]-miu[i-1])*d[n/i]*d[m/i];
    		}
    		printf("%lld
    ",ans);
    	}
        return 0;
    }
    
    +++++++++++++++++++++++++++++++++++++++++++

    +本文作者:luyouqi233。               +

    +欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

    +++++++++++++++++++++++++++++++++++++++++++

  • 相关阅读:
    锐捷交换机密码恢复
    adobe cs3系列产品官方帮助网页(中文)
    网页设计视频教程
    锐捷交换机、路由器配置手册
    WINPE下如何直接删除联想隐藏分区?
    IWMS实现频道页面的方法
    SATA、SCSI、SAS区别与特点
    自定义系统必备
    自己写的Web服务器
    尝试MVP模式
  • 原文地址:https://www.cnblogs.com/luyouqi233/p/8641712.html
Copyright © 2011-2022 走看看