60分TLE求助
查看原帖
60分TLE求助
238861
xzzduang楼主2021/7/15 09:48
#include<iostream>
#include<stdio.h>
#include<map>
#define N 8000001
#define int long long
using namespace std;
inline int read(){
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
	return x*f;
}
map <int,int> mp;
int mo,n,phi[N],pri[N],prs,notp[N],ans,inv2,inv6,M;
int power(int x,int b){
	int res=1;
	while(b){
		if(b&1) res=res*x%mo;
		x=x*x%mo;
		b>>=1;
	}
	return res;
}
void init(){
	phi[1]=1;
	for(int i=2;i<M;++i){
		if(!notp[i]) pri[++prs]=i,phi[i]=i-1;
		for(int j=1;j<=prs && i*pri[j]<M;++j){
			notp[i*pri[j]]=1;
			if(i%pri[j]) phi[i*pri[j]]=phi[i]*(pri[j]-1);
			else{phi[i*pri[j]]=phi[i]*pri[j];break;}
		}
	}
	for(int i=1;i<M;++i) phi[i]=(phi[i]*i%mo*i%mo+phi[i-1])%mo;
}
int sum(int x){x%=mo;return (1+x)*x%mo*inv2%mo;}
int sum2(int x){x%=mo;return x*(x+1)%mo*(x+x+1)%mo*inv6%mo;}
int GetSum(int lim){
	if(lim<M) return phi[lim];
	if(mp.count(lim)) return mp[lim];
	int res=sum(lim)*sum(lim)%mo;
	for(int l=2,r;l<=lim;l=r+1){
		int t=(sum2(r)-sum2(l-1))%mo;
		res=(res-t*GetSum(lim/l)%mo)%mo;
	}
	return mp[lim]=(res+mo)%mo;
}
signed main(){
	mo=read(),n=read();
	M=min(8000000LL,n)+1;
	init();
	inv2=power(2,mo-2);
	inv6=power(6,mo-2);
	for(int l=1,r;l<=n;l=r+1){
		r=n/(n/l);
		int s=sum(n/l)*sum(n/l)%mo;
		int t=(GetSum(r)-GetSum(l-1)+mo)%mo;
		ans=(ans+t*s%mo)%mo;
	}
	cout<<ans;
	return 0;
}

2021/7/15 09:48
加载中...