• 51Nod 2026 Gcd and Lcm


    题目传送门
    分析:
    开始玩一个小小的trick
    我们发现(f(n)=sum_{d|n}mu(d)cdot d)是一个积性函数
    所以:

    (~~~~f(n)=prod f(p_i^{a_i}))
    (~~~~f(gcd(x,y))cdot f(lcm(x,y))=prod f(p_i^{min(a_i,b_i)})cdot f(p_i^{max(a_i,b_i)}))

    可以疯狂使用交换律然后。。。

    (~~~~prod f(p_i^{min(a_i,b_i)})cdot f(p_i^{max(a_i,b_i)})=f(x)cdot f(y))

    接下来就好办了,大力推:

    (~~~~sum_{i=1}^{n}sum_{j=1}^{n}f(gcd(i,j))cdot f(lcm(i,j)))
    (=sum_{i=1}^{n}sum_{j=1}^{n}f(i)cdot f(j))
    (=(sum_{i=1}^{n}f(i))^2)

    我们求里面的:

    (~~~~sum_{i=1}^{n}sum_{d|i}mu(d)cdot d)
    (=sum_{d=1}^{n}mu(d)cdot dcdot lfloorfrac{n}{d} floor)

    分块处理(lfloorfrac{n}{d} floor)
    后面的老套路,卷一个(Id)

    (~~~~sum_{i=1}^{n}sum_{d|i}mu(d)cdot dcdot frac{i}{d}=sum_{i=1}^{n}isum_{d|i}mu(d)=1)
    (=sum_{d=1}^{n}dsum_{i=1}^{lfloorfrac{n}{d} floor}mu(i)cdot i)

    (d=1)提出来:

    (~~~~sum_{i=1}^{n}mu(i)cdot i=1-sum_{d=2}^{n}dsum_{i=1}^{lfloorfrac{n}{d} floor}mu(i)cdot i)
    (~~~~S(n)=1-sum_{d=2}^{n}dcdot S(lfloorfrac{n}{d} floor))

    然后杜教筛就好了

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<iostream>
    #include<map>
    #include<string>
    
    #define maxn 100005
    #define INF 0x3f3f3f3f
    #define MOD 1000000007
    #define inv2 500000004
    
    using namespace std;
    
    inline long long getint()
    {
        long long num=0,flag=1;char c;
        while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
        while(c>='0'&&c<='9')num=num*10+c-48,c=getchar();
        return num*flag;
    }
    
    long long N;
    long long pri[maxn],cnt,np[maxn],mu[maxn];
    long long ans;
    map<long long,long long>M;
    
    inline void init()
    {
    	mu[1]=1;
    	for(int i=2;i<maxn;i++)
    	{
    		if(!np[i])pri[++cnt]=i,mu[i]=-1;
    		for(int j=1;j<=cnt&&i*pri[j]<maxn;j++)
    		{
    			np[i*pri[j]]=1;
    			if(i%pri[j]==0)break;
    			mu[i*pri[j]]=-mu[i];
    		}
    	}
    	for(int i=1;i<maxn;i++)(mu[i]*=i)%=MOD;
    	for(int i=1;i<maxn;i++)(mu[i]+=mu[i-1])%=MOD;
    }
    
    inline long long getans(long long x)
    {
    	if(x<maxn)return mu[x];
    	if(M.count(x))return M[x];
    	long long num=1;
    	for(long long i=2,j;i<=x;i=j+1)
    	{
    		j=x/(x/i);
    		(num+=MOD-(i+j)*(j-i+1)%MOD*inv2%MOD*getans(x/i))%=MOD;
    	}
    	return M[x]=num;
    }
    
    int main()
    {
    	N=getint();
    	init();
    	for(long long i=1,j;i<=N;i=j+1)
    	{
    		j=N/(N/i);
    		(ans+=(N/i)*(getans(j)-getans(i-1)))%=MOD;
    	}
    	printf("%lld
    ",(ans*ans%MOD+MOD)%MOD);
    }
    
    

  • 相关阅读:
    深度学习一:安装MXnet包,实现MNIST手写数体识别
    深度学习二:Neural art:用机器模仿梵高
    【Stanford CNN课程笔记】1. Image Classification and Nearest Neighbor Classifier
    PHP之图形处理
    Ubuntu14.10+cuda7.0+caffe配置
    CentOS系统上编译、安装、配置OpenCV
    安装MXnet包,实现MNIST手写数体识别
    Neural art:用机器模仿梵高
    String to Integer (atoi)
    Wildcard Matching
  • 原文地址:https://www.cnblogs.com/Darknesses/p/12194006.html
Copyright © 2020-2023  润新知