把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

luogu P3768 简单的数学题

题面传送门
一道神仙题目。
枚举个gcd把原式化为\(\sum\limits_{d=1}^{n}{d^3\sum\limits_{i=1}^{n}{\sum\limits_{j=1}^{n}{ij[gcd(i,j)=1]}}}\)
\(sum(n)=\sum\limits_{i=1}^{n}{i}\)那么那个式子莫反一下就是\(\sum\limits_{k=1}^{n}{k^3\sum\limits_{d=1}^{n}{\mu(d)d^2sum(\frac{n}{kd})^2}}\)
\(T=kd\),那么有\(\sum\limits_{T=1}^{n}{sum(\frac{n}{T})^2\sum\limits_{d|T}{\mu(d)d^2(\frac{T}{d})^3}}\)
化简一下就是\(\sum\limits_{T=1}^{n}{sum(\frac{n}{T})^2T^3\sum\limits_{d|T}{\frac{\mu(d)}{d}}}\)
然后根据狄利克雷卷积的经典结论就是\(\mu*I=\phi\),就可以化成\(\sum\limits_{T=1}^{n}{sum(\frac{n}{T})^2T^2\phi(T)}\)
前面那个可以整除分块求,后面那个考虑杜教筛处理。
我们知道\(\phi*I=id\),那么如果我们让\(T^2\phi(T)\)卷上\(T^2\),那么就会抵消掉,最后剩下\(T^3\)
所以就可以筛了。
时间复杂度\(O(n^{\frac{2}{3}})\)
code:

#include <vector>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
#include<algorithm>
#include<bitset>
#include<set>
#include<map>
#define I inline
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define l(x) x<<1
#define r(x) x<<1|1
#define re register
#define ll long long
#define db long double
#define N 20000000
#define eps (1e-14)
#define mod 998244353
#define U unsigned
using namespace std;
ll n,ans,tot,phi[N+5],inv2,inv6;int p,m=N,fl[N+5],pr[N+5],ph;map<ll,ll> g;
I ll mpow(ll x,int y=p-2){ll ans=1;while(y) y&1&&(ans=ans*x%p),x=x*x%p,y>>=1;return ans;}
I ll sum1(ll x){x%=p;return x*(x+1)%p*inv2%p;}
I ll sum2(ll x){x%=p;return x*(x+1)%p*(2*x+1)%p*inv6%p;}
I ll Getphi(ll n){
	if(n<=m)return phi[n];if(g[n]) return g[n];ll res=sum1(n),i,j;res=res*res%p;
	for(i=2;i<=n;i=j+1) j=n/(n/i),res-=(sum2(j)-sum2(i-1))%p*Getphi(n/i)%p;res=(res%p+p)%p;return g[n]=res;
}
int main(){
	//freopen("1.in","r",stdin);
	 re ll i,j;scanf("%d%lld",&p,&n);phi[1]=1;inv2=mpow(2);inv6=mpow(6);m=pow(n,2.0/3);
	for(i=2;i<=m;i++){
		!fl[i]&&(pr[++ph]=i,phi[i]=i-1);for(j=1;j<=ph&&i*pr[j]<=m;j++){
			fl[i*pr[j]]=1;if(i%pr[j]==0){phi[i*pr[j]]=phi[i]*pr[j];break;}
			phi[i*pr[j]]=phi[i]*phi[pr[j]];
		}
	}
	for(i=1;i<=m;i++) phi[i]=(phi[i]*i%p*i+phi[i-1])%p;Getphi(2);
	for(i=1;i<=n;i=j+1)j=n/(n/i),tot=sum1(n/i),ans+=tot*tot%p*(Getphi(j)-Getphi(i-1))%p;printf("%lld\n",(ans%p+p)%p);
}
posted @ 2021-06-03 21:00  275307894a  阅读(39)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end