1 条题解

  • 0
    @ 2025-10-8 17:09:58

    #include<bits/stdc++.h>
    using namespace std;
    template<typename T> void qread(T &x){
    	x=0; int f=1; char c=getchar();
    	for(; !isdigit(c); c=getchar()) if(c=='-') f=-1;
    	for(; isdigit(c); c=getchar()) x=x*10+(c-'0');
    	x*=f;
    }
    typedef long long LL;
    const int N=5e6+10;
    const LL P=1e9+7;
    int pr, prime[N];
    bool v[N];
    LL mu[N];
    void init(){
    	pr=0; memset(v, 0, sizeof(v));
    	mu[0]=0; mu[1]=1;
    	for(int i=2; i<=N-10; i++){
    		if(!v[i]) pr++, prime[pr]=i, mu[i]=-1;
    		for(int j=1; (j<=pr) && (i*prime[j]<=N-10); j++){
    			int p=prime[j];
    			v[i*p]=1;
    			if(i%p==0){
    				mu[i*p]=0;
    				break;
    			}
    			else mu[i*p]=-mu[i];
    		}
    	}
    	for(int i=1; i<=N-10; i++) mu[i]+=mu[i-1];
    }
    LL sub(LL a, LL b){
    	return ((a-b)%P+P)%P;
    }
    map<LL, LL> hs;
    LL calc(LL x){
    	if(x<=N-10) return mu[x];
    	if(hs[x]) return hs[x];
    	LL res=1;
    	for(int i=2, j; i<=x; i=j+1){
    		j=x/(x/i);
    		res=sub(res, calc(x/i)*(j-i+1)%P);
    	}
    	return hs[x]=res;
    }
    LL getsum(LL x){
    	LL res=0;
    	for(int i=1, j; i<=x; i=j+1){
    		j=x/(x/i);
    		res=(res+(x/i)*(j-i+1)%P)%P; 
    	}
    	return res;
    }
    LL solve(LL x){
    	LL res=0;
    	for(int i=1, j; i<=x; i=j+1){
    		j=x/(x/i);
    		LL t=getsum(x/i);
    		res=(res+sub(calc(j), calc(i-1))*t%P*t%P)%P;
    	}
    	return res;
    }
    int main(){
    	init();
    	LL n; qread(n);
    	printf("%lld\n", solve(n));
    	return 0;
    }
    
    • 1

    *【莫比乌斯反演】i*j的约数个数和②[Lucas的数论]

    信息

    ID
    5841
    时间
    2000ms
    内存
    128MiB
    难度
    10
    标签
    递交数
    8
    已通过
    2
    上传者