[洛谷3768]简单的数学题

题目链接:https://www.luogu.org/problemnew/show/P3768

看到\(\gcd\)我们就来套路一波,枚举因数可得

\[\sum\limits_{d=1}^nd^3\sum\limits_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{n}{d}\rfloor}ij[\gcd(i,j)=1] \]

然后对最后的\(\gcd\)反演得

\[\sum\limits_{d=1}^nd^3\sum\limits_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{n}{d}\rfloor}ij\sum\limits_{x|i,x|j}\mu(x) \]

然后我们更改一下枚举顺序得

\[\sum\limits_{d=1}^nd^3\sum\limits_{x=1}^{\lfloor\frac{n}{d}\rfloor}\mu(x)\sum\limits_{i=1}^{\lfloor\frac{n}{dx}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{n}{dx}\rfloor}x^2ij \]

\[\sum\limits_{d=1}^nd^3\sum\limits_{x=1}^{\lfloor\frac{n}{d}\rfloor}x^2\mu(x)(\sum\limits_{i=1}^{\lfloor\frac{n}{dx}\rfloor}i)^2 \]

然后我们设\(h(x)=\sum\limits_{i=1}^ni\),令\(T=dx\),然后再次更改枚举顺序可得

\[\sum\limits_{T=1}^nh(\dfrac{n}{T})^2\sum\limits_{d|T}d^3×(\dfrac{T}{d})^2\mu(\dfrac{T}{d}) \]

\[\sum\limits_{T=1}^nh(\dfrac{n}{T})^2\sum\limits_{d|T}T^2d\mu(\dfrac{T}{d}) \]

\(T^2\)那东西可以提到外面,于是里面只剩下\(\sum\limits_{d|T}d\mu(\dfrac{T}{d})\),这是个卷积形式,卷积后的结果即为\(\varphi(T)\),我们设\(f(T)=T^2\varphi(T)\),那么原式变为

\[\sum\limits_{T=1}^nh(\dfrac{n}{T})^2f(T) \]

那么我们只要求出\(f(T)\)的前缀和,我们就可以数论分块\(O(\sqrt n)\)做完这题了

然后你发现这题\(n\leqslant 10^{10}\),然后线筛肯定不行……我们需要用到杜教筛

然后我们需要找到一个优秀的\(g\),使得\(\sum\limits_{i=1}^n(f*g)(i)\)能够在\(O(1)\)的时间内算出来,根据人类智慧(其实是打表),当\(g(i)=i^2\)时,可以得到

\[\begin{aligned}(f*g)(n)&=\sum\limits_{d|n}f(d)g(\dfrac{n}{d})\\&=\sum\limits_{d|n}d^2\varphi(d)(\dfrac{n}{d})^2\\&=n^2\sum\limits_{d|n}\varphi(d)\\&=n^3\end{aligned} \]

所以\(\sum\limits_{i=1}^n(f*g)(i)=\sum\limits_{i=1}^ni^3\),这东西的前缀和是很好算的,为\(h(n)^2\)(证明请自行Google),于是我们可以用杜教筛得到\(f(T)\)的前缀和,配合之前的式子进行一下数论分块即可

/*program from Wolfycz*/
#include<map>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define Fi first
#define Se second
#define inf 0x7f7f7f7f
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
inline char gc(){
	static char buf[1000000],*p1=buf,*p2=buf;
	return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
}
inline int frd(){
	int x=0,f=1; char ch=gc();
	for (;ch<'0'||ch>'9';ch=gc())	if (ch=='-')	f=-1;
	for (;ch>='0'&&ch<='9';ch=gc())	x=(x<<3)+(x<<1)+ch-'0';
	return x*f;
}
inline int read(){
	int x=0,f=1; char ch=getchar();
	for (;ch<'0'||ch>'9';ch=getchar())	if (ch=='-')	f=-1;
	for (;ch>='0'&&ch<='9';ch=getchar())	x=(x<<3)+(x<<1)+ch-'0';
	return x*f;
}
inline void print(int x){
	if (x<0)	putchar('-'),x=-x;
	if (x>9)	print(x/10);
	putchar(x%10+'0');
}
const int N=1e7;
int prime[N+10],phi[N+10],sh[N+10];//sh(x)=\sum\limits_{i=1}^i h(i); h(x)=x^2*\varphi(x)
bool inprime[N+10];
int p,inv2,inv4,inv6;
map<ll,int>Mp;
void prepare(){
	sh[1]=phi[1]=1; int tot=0;
	for (int i=2;i<=N;i++){
		if (!inprime[i])	prime[++tot]=i,phi[i]=i-1;
		for (int j=1;j<=tot&&i*prime[j]<=N;j++){
			inprime[i*prime[j]]=1;
			if (i%prime[j]==0){
				phi[i*prime[j]]=phi[i]*prime[j];
				break;
			}
			phi[i*prime[j]]=phi[i]*(prime[j]-1);
		}
		sh[i]=(sh[i-1]+1ll*i*i%p*phi[i]%p)%p;
	}
}
int s2(ll n){n%=p;return 1ll*(2*n+1)*(n+1)%p*n%p*inv6%p;}
int SH(ll n){
	if (n<=N)	return sh[n];
	map<ll,int>::iterator it=Mp.find(n);
	if (it!=Mp.end())	return it->Se;
	int tmp=n%p,res=1ll*tmp*tmp%p*(tmp+1)%p*(tmp+1)%p*inv4%p;
	for (ll i=2,pos;i<=n;i=pos+1){
		pos=n/(n/i);
		res=(res-1ll*(s2(pos)-s2(i-1))*SH(n/i)%p)%p;
	}
	res=(res+p)%p;
	Mp.insert(map<ll,int>::value_type(n,res));
	return res;
}
int s1(ll n){n%=p;return 1ll*n*(n+1)%p*inv2%p;}
int mlt(int a,int b){
	int res=1;
	for (;b;b>>=1,a=1ll*a*a%p)	if (b&1)	res=1ll*res*a%p;
	return res;
}
int main(){
	ll n;
	scanf("%d%lld",&p,&n);
	inv2=mlt(2,p-2);
	inv4=mlt(4,p-2);
	inv6=mlt(6,p-2);
	prepare(); int Ans=0;
	for (ll i=1,pos;i<=n;i=pos+1){
		pos=n/(n/i);
		Ans=(Ans+1ll*(SH(pos)-SH(i-1))*s1(n/i)%p*s1(n/i)%p)%p;
	}
	printf("%d\n",(Ans+p)%p);
	return 0;
}
posted @ 2019-03-21 19:21  Wolfycz  阅读(202)  评论(0编辑  收藏  举报