2 条题解

  • 0
    @ 2025-10-8 17:11:28
    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1e7 + 10;
    typedef long long LL;
    int prime[N], pr, phi[N];
    //prime存质数,pr代表现在筛出来了几个质数,phi存欧拉函数 
    LL sp[N]; //欧拉函数前缀和 
    bool v[N];
    void init() {
        pr = 0; phi[1] = 1; //欧拉函数初始化,1就是 1 
        memset(v, 0, sizeof(v));
        for (int i = 2; i <= N; i++) {
            if (v[i] == 0) prime[++pr] = i, phi[i] = i - 1;
            for (int j = 1; (j <= pr) && (i * prime[j] <= N - 10); j++) {
                v[i * prime[j]] = 1;
                if (i % prime[j] == 0) {
                    phi[i * prime[j]] = phi[i] * prime[j];
                    break;
                } else {
                    phi[i * prime[j]] = phi[i] * (prime[j] - 1);                          
                }
            }
        }
        sp[0] = 0;
        for (int i = 1; i <= N - 10; i++) sp[i] = sp[i - 1] + phi[i];
    } 
    map<LL, LL> hs;
    LL solve(LL x) {
        if (x <= N - 10) return sp[x];
        if (hs[x]) return hs[x];
        LL res = 0;
        for (LL i = 2, j; i <= x; i = j + 1) {
            j = x / (x / i);
            //分块加速 x/i都一样的 i分成一块,一块块的计算
            //这里 j是 x/j=x/i 中的最大的 j 
            res += (j - i + 1) * solve(x / i);
        }
        return hs[x] = x * (x + 1) / 2 - res;
    }
    int main() {
        init();
        LL n; scanf("%lld", &n);
        printf("%lld\n", solve(n));
        return 0;
    }
    
    • 0
      @ 2025-10-8 17:11:18
      #include<bits/stdc++.h>
      using namespace std;
      const int N=1e7+10;
      typedef long long LL;
      int prime[N], pr, phi[N];
      //prime存质数,pr代表现在筛出来了几个质数,phi存欧拉函数 
      LL sp[N]; //欧拉函数前缀和 
      bool v[N];
      void init(){
      	pr=0; phi[1]=1; //欧拉函数初始化,1就是 1 
      	memset(v, 0, sizeof(v));
      	for(int i=2; i<=N; i++)
      	{
      		if(v[i]==0) prime[++pr]=i, phi[i]=i-1;
      		for(int j=1; (j<=pr)&&(i*prime[j]<=N-10); j++)
      		{
      			v[i*prime[j]]=1;
      			if(i%prime[j]==0){
      				phi[i*prime[j]]=phi[i]*prime[j];
      				break;
      			}
      			else{
      				phi[i*prime[j]]=phi[i]*(prime[j]-1);                          
      			}
      		}
      	}
      	sp[0]=0;
      	for(int i=1; i<=N-10; i++) sp[i]=sp[i-1]+phi[i];
      } 
      map<LL, LL> hs;
      LL solve(LL x){
      	if(x<=N-10) return sp[x];
      	if(hs[x]) return hs[x];
      	LL res=0;
      	for(LL i=2, j; i<=x; i=j+1){
      		j=x/(x/i);
      		//分块加速 x/i都一样的 i分成一块,一块块的计算
      		//这里 j是 x/j=x/i 中的最大的 j 
      		res+=(j-i+1)*solve(x/i);
      	}
      	return hs[x]=x*(x+1)/2-res;
      }
      int main(){
      	init();
      	LL n; scanf("%lld",&n);
      	printf("%lld\n", solve(n));
      	return 0;
      }
      • 1

      *【莫比乌斯反演:杜教筛】 欧拉函数求和

      信息

      ID
      6474
      时间
      1000ms
      内存
      256MiB
      难度
      9
      标签
      递交数
      14
      已通过
      3
      上传者