杜教筛新人求救
查看原帖
杜教筛新人求救
114153
Saliеri楼主2020/5/29 09:48

样例都过不了(如果问题太傻不要嘲讽我)

#include <cmath>
#include <cstdio>
#include <unordered_map>
const int MAXN = 5000005;
typedef long long LL;
LL n,p,maxn;
int pr,prime[MAXN],vis[MAXN];
long long phi[MAXN];
std :: unordered_map<int,LL> phisum;
void sieve(){
	phi[1] = 1;
	for(int i=2;i<=maxn;++i){
		if(!vis[i])phi[i] = i-1,prime[++pr] = i;
		for(int j=1;j<=pr&&prime[j]*i<=maxn;++j){
			vis[i*prime[j]] = 1;
			if(i % prime[j] == 0){
				phi[i*prime[j]] = phi[i]*prime[j]%p;
				break;
			}
			phi[i*prime[j]] = (prime[j]-1)*phi[i]%p;
		}
	}
	for(int i=1;i<=maxn;++i)phi[i] = phi[i]*i%p*i%p;
	for(int i=1;i<=maxn;++i)phi[i] = (phi[i] + phi[i-1])%p;
}
inline LL H(LL N){
	return (N*(N+1)/2%p)*(N*(N+1)/2%p)%p;
}
LL getphi(LL N){
	if(N <= maxn)return phi[N];
	if(phisum[N])return phisum[N];
	LL res = 0;
	for(LL l=2,r;l<=N;l=r+1){
		r = N/(N/l);
		res = (res+(r-l+1)*getphi(N/l)%p)%p;
	}
	return phisum[N] = (H(N) - res + p)%p;
}
LL getans(LL N){
	LL res = 0;
	for(LL l=1,r;l<=N;l=r+1){
		r = N/(N/l);
		res = (res+((getphi(r)-getphi(l-1))%p+p)%p*H(N/l)%p)%p;
	}
	return res;
} 
int main(){
	scanf("%lld %lld",&p,&n);
	maxn = std :: pow(n,0.6666);
	sieve();
	getphi(n);
	printf("%lld",getans(n));
	return 0;
}
2020/5/29 09:48
加载中...