2 条题解
-
0
#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
#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
信息
- ID
- 464
- 时间
- 4000ms
- 内存
- 256MiB
- 难度
- 7
- 标签
- 递交数
- 27
- 已通过
- 8
- 上传者