2 条题解

  • 0
    @ 2025-10-8 16:50:45
    #include<bits/stdc++.h>
    using namespace std;
    const int N=5e6+10; 
    typedef long long LL;
    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;
    }
    LL P, n;
    int phi[N], pr, prime[N]; //phi不能开longlong会炸 
    LL sp[N], invtwo, invsix;
    bool v[N];
    void init(){
    	pr=0; memset(v, 0, sizeof(v));
    	phi[1]=1;
    	for(int i=2; i<=N-10; i++){
    		if(!v[i]){
    			pr++; prime[pr]=i;
    			phi[i]=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){
    				phi[i*p]=phi[i]*p;
    				break;
    			}
    			else{
    				phi[i*p]=phi[i]*phi[p];
    			}
    		} 
    	}
    	sp[0]=0;
    	for(int i=1; i<=N-10; i++){
    		sp[i]=(sp[i-1]+1LL*phi[i] *i%P*i)%P;
    	}
    }
    LL q_pow(LL a, LL b){
    	LL res=1;
    	while(b){
    		if(b&1) res=res*a%P;
    		a=a*a%P; b/=2;
    	}
    	return res;
    }
    LL powsum(LL x){ //平方和数列求和 
    	x%=P;
    	return x*(x+1)%P*(2*x+1)%P*invsix%P;
    }
    LL getsum(LL x){ //自然数数列求和平方(就是i^3立方和数列的求和) 
    	x%=P;
    	LL t=x*(x+1)%P*invtwo%P;
    	return t*t%P;
    }
    map<LL, LL> hsp;
    LL calc(LL x){ //欧拉函数*i*i求和 
    	if(x<=N-10) return sp[x];
    	if(hsp[x]) return hsp[x];
    	LL res=getsum(x)%P;
    	for(LL i=2, j; i<=x; i=j+1){
    		j=x/(x/i);
    		LL t=((powsum(j)-powsum(i-1))%P+P)%P;
    		res=((res-t*calc(x/i)%P)+P)%P;
    	}
    	return hsp[x]=res;
    }
    LL solve(LL x){
    	LL res=0;
    	for(LL i=1, j; i<=x; i=j+1){
    		j=x/(x/i);
    		LL t=getsum(x/i)%P;
    		res=(res+((calc(j)-calc(i-1))%P+P)%P*t%P)%P;
    	}
    	return res;
    }
    int main(){
    	qread(P); qread(n);
    	invtwo=q_pow(2, P-2);
    	invsix=q_pow(6, P-2);
    	init();
    	printf("%lld\n", solve(n));
    	return 0;
    }
    
    • 0
      @ 2025-10-8 16:50:32
      #include<bits/stdc++.h>
      using namespace std;
      const int N=5e6+10; 
      typedef long long LL;
      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;
      }
      LL P, n;
      int phi[N], pr, prime[N]; //phi不能开longlong会炸 
      LL sp[N], invtwo, invsix;
      bool v[N];
      void init(){
      	pr=0; memset(v, 0, sizeof(v));
      	phi[1]=1;
      	for(int i=2; i<=N-10; i++){
      		if(!v[i]){
      			pr++; prime[pr]=i;
      			phi[i]=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){
      				phi[i*p]=phi[i]*p;
      				break;
      			}
      			else{
      				phi[i*p]=phi[i]*phi[p];
      			}
      		} 
      	}
      	sp[0]=0;
      	for(int i=1; i<=N-10; i++){
      		sp[i]=(sp[i-1]+1LL*phi[i] *i%P*i)%P;
      	}
      }
      LL q_pow(LL a, LL b){
      	LL res=1;
      	while(b){
      		if(b&1) res=res*a%P;
      		a=a*a%P; b/=2;
      	}
      	return res;
      }
      LL powsum(LL x){ //平方和数列求和 
      	x%=P;
      	return x*(x+1)%P*(2*x+1)%P*invsix%P;
      }
      LL getsum(LL x){ //自然数数列求和平方(就是i^3立方和数列的求和) 
      	x%=P;
      	LL t=x*(x+1)%P*invtwo%P;
      	return t*t%P;
      }
      map<LL, LL> hsp;
      LL calc(LL x){ //欧拉函数*i*i求和 
      	if(x<=N-10) return sp[x];
      	if(hsp[x]) return hsp[x];
      	LL res=getsum(x)%P;
      	for(LL i=2, j; i<=x; i=j+1){
      		j=x/(x/i);
      		LL t=((powsum(j)-powsum(i-1))%P+P)%P;
      		res=((res-t*calc(x/i)%P)+P)%P;
      	}
      	return hsp[x]=res;
      }
      LL solve(LL x){
      	LL res=0;
      	for(LL i=1, j; i<=x; i=j+1){
      		j=x/(x/i);
      		LL t=getsum(x/i)%P;
      		res=(res+((calc(j)-calc(i-1))%P+P)%P*t%P)%P;
      	}
      	return res;
      }
      int main(){
      	qread(P); qread(n);
      	invtwo=q_pow(2, P-2);
      	invsix=q_pow(6, P-2);
      	init();
      	printf("%lld\n", solve(n));
      	return 0;
      }
      • 1

      G40*【莫比乌斯反演:杜教筛2】i*j*gcd(i,j)求和2 [P3768]简单的数学题(没数据)

      信息

      ID
      464
      时间
      4000ms
      内存
      256MiB
      难度
      7
      标签
      递交数
      27
      已通过
      8
      上传者