数论习题(一)

(一).推式子题

- P2568 GCD

给定 \(n\),求:

\[\sum\limits_{p\in\mathbb{P}}\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}[\gcd(i,j)=p] \]

其中 \(\mathbb{P}\) 为质数集。

推式子:

\[\begin{aligned}\sum\limits_{p\in\mathbb{P}}\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}[\gcd(i,j)=p] &= \sum\limits_{p\in\mathbb{P}}\sum\limits_{i=1}^{\lfloor\frac{n}{p}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{n}{p}\rfloor}[\gcd(i,j)=1] \\&= \sum\limits_{p\in\mathbb{P}}\Bigg(\sum\limits_{i=1}^{\lfloor\frac{n}{p}\rfloor} \Big(2\cdot \sum\limits_{j=1}^{i}[\gcd(i,j)=1]\Big) -1\Bigg) &……\text{①} \\&=\sum\limits_{p\in\mathbb{P}}\Bigg(\sum\limits_{i=1}^{\lfloor\frac{n}{p}\rfloor}\Big( 2\varphi(i) \Big)-1\Bigg) \end{aligned}\]

\(\text{①}\):感性理解,\(\lfloor\frac{n}{p}\rfloor\) 以内的互质数对对数,等于二倍的 \(i\ge j\) 的对数,减掉重复计算的 \((1,1)\) 数对。

线性筛 \(\varphi\) 并求前缀和,枚举 \(p\) 统计即可。

提交记录

点击查看代码
//#pragma GCC optimize(2)
//#pragma GCC optimize(3)
//#pragma GCC optimize("Ofast","inline")
#include<bits/stdc++.h>
#define fr(a) freopen(a,"r",stdin)
#define fw(a) freopen(a,"w",stdout)
using namespace std;
typedef long long ll;
const int MAXN=1e7+10;
ll n,prime[MAXN],phi[MAXN],v[MAXN],tot,sumphi[MAXN];
ll ans;
void shai(){//欧拉筛求质数&欧拉函数
	phi[1]=1;
	for(int i=2;i<=n;i++){
		if(v[i]==0){
			v[i]=i;prime[++tot]=i;
			phi[i]=i-1;
		}
		for(int j=1;j<=tot;j++){
			if(prime[j]>v[i] || prime[j] > n/i) break;
			v[i*prime[j]]=prime[j];
			if(i%prime[j]==0) phi[i*prime[j]] =phi[i] * prime[j];
			else phi[i*prime[j]] =phi[i] *(prime[j]-1);
		}
	}
	for(int i=1;i<=n;i++) phi[i]+=phi[i-1];
}
int main(){
	scanf("%lld",&n);
	shai();
	for(int i=1;i<=tot;i++) ans+=2*phi[n/prime[i]]-1;
	printf("%lld\n",ans);
	return 0;
}

- P2398 GCD SUM

给定 \(n\),求:

\[\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}\gcd(i,j) \]

枚举 \(\gcd\),枚举推式子:

\[\begin{aligned}\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{n}\gcd(i,j) &=\sum\limits_{d=1}^{n}\Big(d\cdot\sum\limits_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{n}{d}\rfloor}[\gcd(i,j)=1]\Big) \\&=\sum\limits_{d=1}^{n}\Bigg(d\cdot\Big(\sum\limits_{i=1}^{\lfloor\frac{n}{d}\rfloor}( 2\varphi{\scriptstyle(i)} )-1\Big)\Bigg) &\text{和上一题一样的操作} \end{aligned}\]

\(\varphi\),前缀和,枚举 \(d\),搞定!

提交记录

点击查看代码
//#pragma GCC optimize(2)
//#pragma GCC optimize(3)
//#pragma GCC optimize("Ofast","inline")
#include<bits/stdc++.h>
#define fr(a) freopen(a,"r",stdin)
#define fw(a) freopen(a,"w",stdout)
#define MP(a,b) make_pair(a,b)
#define DEBUG
using namespace std;
typedef long long ll;
const int N=1e5+10;
ll n;
ll prime[N],v[N],phi[N],tot;
void shai(){//欧拉筛求质数&欧拉函数
	phi[1]=1;
	for(int i=2;i<=n;i++){
		if(v[i]==0){
			v[i]=i;prime[++tot]=i;
			phi[i]=i-1;
		}
		for(int j=1;j<=tot;j++){
			if(prime[j]>v[i] || prime[j] > n/i) break;
			v[i*prime[j]]=prime[j];
			if(i%prime[j]==0) phi[i*prime[j]] =phi[i] * prime[j];
			else phi[i*prime[j]] =phi[i] *(prime[j]-1);
		}
	}
	for(int i=1;i<=n;i++) phi[i]+=phi[i-1];
}
int main(){
	scanf("%lld",&n);ll ans=0;
	shai();
	for(int d=1;d<=n;d++){
		ans+=d*(2*phi[n/d] -1);
	}printf("%lld\n",ans);
	return 0;
}


- P2522 [HAOI2011] Problem b

给定 \(1\le (a\le b,c\le d,k) \le 5\cdot 10^4\),求:

\[\sum\limits_{i=a}^{b}\sum\limits_{j=c}^{d}[\gcd(i,j)=k] \]

先通过容斥拆成四部分:记 \(A=\lceil\frac{a}{k}\rceil,B=\lfloor\frac{b}{k}\rfloor,C=\lceil\frac{c}{k}\rceil,D=\lfloor\frac{d}{k}\rfloor\)

\[\begin{aligned}&\sum\limits_{i=a}^{b}\sum\limits_{j=c}^{d}[\gcd(i,j)=k] =\sum\limits_{i=A}^{B}\sum\limits_{j=C}^{D}[\gcd(i,j)=1] \\=&\sum\limits_{i=1}^{B}\sum\limits_{j=1}^{D}[\gcd(i,j)=1]-\sum\limits_{i=1}^{B}\sum\limits_{j=1}^{C-1}[\gcd(i,j)=1]-\sum\limits_{i=1}^{A-1}\sum\limits_{j=1}^{D}[\gcd(i,j)=1]+\sum\limits_{i=1}^{A-1}\sum\limits_{j=1}^{C-1}[\gcd(i,j)=1]\end{aligned}\]

\(f(n,m)=\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}[\gcd(i,j)=1]\),则

\(\text{原式}=f(B,D)-f(B,C-1)-f(A-1,D)+f(A-1,C-1)\)

开始推 \(f\)

\(\begin{aligned}f(n,m)&=\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}[\gcd(i,j)=1] \\ &=\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}\sum\limits_{d\mid \gcd(i,j)}\mu(d) &\text{好像是莫反的结论?} \\&=\sum\limits_{d=1}^{\min(n,m)} \Big(\mu(d) \cdot \sum\limits_{i=1}^{n}[d\mid i] \cdot \sum\limits_{j=1}^{m} [d\mid j]\Big) &\text{更换求和顺序,感性理解} \\&=\sum\limits_{d=1}^{\min(n,m)} \Big(\mu(d) \lfloor\frac{n}{d}\rfloor \lfloor\frac{m}{d}\rfloor\Big) &n\text{ 以内 }d\text{ 的倍数一共有 } \lfloor\frac{n}{d}\rfloor \text{ 个} \end{aligned}\)

最后这个式子可以数论分块求,这样这道题就做完了。

提交记录

点击查看代码
//#pragma GCC optimize(2)
//#pragma GCC optimize(3)
//#pragma GCC optimize("Ofast","inline")
#include<bits/stdc++.h>
#define fr(a) freopen(a,"r",stdin)
#define fw(a) freopen(a,"w",stdout)
#define MP(a,b) make_pair(a,b)
#define DEBUG
using namespace std;
typedef long long ll;
const int N=5e4+10;
ll T=1;
ll a,b,c,d,k;
ll prime[N],v[N],mu[N],tot,summu[N];
void shai(){
	mu[1]=1;
	for(int i=2;i<=N-10;i++){
		if(v[i]==0){
			v[i]=i;prime[++tot]=i;
			mu[i]=-1;
		}
		for(int j=1;j<=tot;j++){
			if(prime[j]>v[i] || prime[j] > (N-10)/i) break;
			v[i*prime[j]]=prime[j];
			if(i % prime[j]==0) mu[i*prime[j]]=0;
			else mu[i*prime[j]]=-mu[i];
		}
	}
	for(int i=1;i<=N-10;i++) summu[i]=summu[i-1]+mu[i];
}
ll calc(ll n,ll m){
	ll res=0,l=1,lim=min(n,m);bool Out=0;
	while(l<=lim){
		ll pn=n/l,pm=m/l;
		ll r=min(n/pn,m/pm);
		if(r>=lim) r=lim,Out=1;
		res+=(summu[r]-summu[l-1]) * pn * pm;
		if(Out) break;
		l=r+1;
	}
	return res;
}
ll calc2(ll n,ll m){
	ll res=0;
	for(int d=1;d<=min(n,m);d++){
		res+=mu[d] * (n/d) * (m/d);
	}return res;
}
int main(){
	shai();
	scanf("%lld",&T);
	for(int Case=1;Case<=T;Case++){
		scanf("%lld%lld%lld%lld%lld",&a,&b,&c,&d,&k);
		ll ans=0;
		ll A=ceil((double)a/k)-1,B=b/k,C=ceil((double)c/k)-1,D=d/k;
		ans=calc(B,D)-calc(B,C)-calc(A,D)+calc(A,C);
		printf("%lld\n",ans);
	}
	return 0;
}

- P1829 [国家集训队] Crash的数字表格 / JZPTAB

给定 \(n,m\),求:

\[\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}\operatorname{lcm}(i,j) \]

由小学奥数可知:\(\operatorname{lcm}(i,j)=\frac{ij}{\gcd(i,j)}\),所以:

\[\begin{aligned} \sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}\operatorname{lcm}(i,j)&=\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}\frac{ij}{\gcd(i,j)} \\ &=\sum\limits_{D=1}^{\min(n,m)}\Bigg(\frac{1}{D}\cdot\sum\limits_{i=1}^{\lfloor\frac{n}{D}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{m}{D}\rfloor}\Big([\gcd(i,j)=1]ijD^2\Big)\Bigg) \\ &=\sum\limits_{D=1}^{\min(n,m)}\Bigg(D\cdot\sum\limits_{i=1}^{\lfloor\frac{n}{D}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{m}{D}\rfloor}\Big([\gcd(i,j)=1]ij\Big)\Bigg) \end{aligned}\]

接下来我们化简括号内,\(D\) 之后的一部分(记为 \(f(n,m)\)):

\[\begin{aligned} f(n,m)&=\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}\Big([\gcd(i,j)=1]ij\Big) \\ &=\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}\Big( (\sum\limits_{d\mid \gcd(i,j)}\mu{\scriptstyle(d)}) ij\Big) \\ &=\sum\limits_{d=1}^{\min(n,m)}\Bigg(\mu(d)\cdot \sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}\Big([d\mid i][d\mid j]ij\Big)\Bigg) \end{aligned}\]

此式中 \(\mu(d)\) 之后的一部分,相当于这个东西:

\[\begin{aligned} &(d+2d+\ldots+\lfloor\frac{n}{d}\rfloor d)\cdot (d+2d+\ldots+\lfloor\frac{m}{d}\rfloor d) \\=&d^2\cdot (1+2+\ldots+\lfloor\frac{n}{d}\rfloor)\cdot (1+2+\ldots+\lfloor\frac{m}{d}\rfloor ) \end{aligned} \]

所以:

\[f(n,m)=\sum\limits_{d=1}^{\min(n,m)}\Bigg(\mu(d)\cdot d^2\cdot\sum\limits_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{m}{d}\rfloor}\Big(ij\Big)\Bigg) \]

而中间那个求和符号:

\[\sum\limits_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{m}{d}\rfloor}\Big(ij\Big) =(\sum\limits_{i=1}^{\lfloor\frac{n}{d}\rfloor} i) \cdot (\sum\limits_{i=1}^{\lfloor\frac{m}{d}\rfloor} j) =\frac{\lfloor\frac{m}{d}\rfloor(\lfloor\frac{m}{d}\rfloor+1)}{2}\cdot \frac{\lfloor\frac{n}{d}\rfloor(\lfloor\frac{n}{d}\rfloor+1)}{2} \]

所以:

\[f(n,m)=\sum\limits_{d=1}^{\min(n,m)}\Bigg(\mu(d)\cdot d^2\cdot\frac{\lfloor\frac{m}{d}\rfloor(\lfloor\frac{m}{d}\rfloor+1)}{2}\cdot \frac{\lfloor\frac{n}{d}\rfloor(\lfloor\frac{n}{d}\rfloor+1)}{2}\Bigg) \]

\(f\) 就可以用数论分块来算。

而原式显然也可以数论分块来做,两个合二为一就能过掉此题了。

最后放一下原式最终的样子:

\[\begin{aligned} &\sum\limits_{D=1}^{\min(n,m)}\Bigg(D\cdot\sum\limits_{i=1}^{\lfloor\frac{n}{D}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{m}{D}\rfloor}\Big([\gcd(i,j)=1]ij\Big)\Bigg) =\sum\limits_{D=1}^{\min(n,m)}\Bigg(D\cdot f(\lfloor\frac{n}{D}\rfloor,\lfloor\frac{m}{D}\rfloor)\Bigg) \\ =&\sum\limits_{D=1}^{\min(n,m)}\Bigg(D\cdot \sum\limits_{d=1}^{\min(\lfloor\frac{n}{D}\rfloor,\lfloor\frac{m}{D}\rfloor)}\Big(\mu(d)\cdot d^2\cdot\frac{\lfloor\frac{\lfloor\frac{n}{D}\rfloor}{d}\rfloor(\lfloor\frac{\lfloor\frac{n}{D}\rfloor}{d}\rfloor+1)}{2}\cdot \frac{\lfloor\frac{\lfloor\frac{m}{D}\rfloor}{d}\rfloor(\lfloor\frac{\lfloor\frac{m}{D}\rfloor}{d}\rfloor+1)}{2}\Big)\Bigg) \end{aligned} \]

提交记录

点击查看代码
//#pragma GCC optimize(2)
//#pragma GCC optimize(3)
//#pragma GCC optimize("Ofast","inline")
#include<bits/stdc++.h>
#define fr(a) freopen(a,"r",stdin)
#define fw(a) freopen(a,"w",stdout)
#define MP(a,b) make_pair(a,b)
#define DEBUG
using namespace std;
typedef long long ll;
const int N=1e7+10,mod=20101009,inv2=10050505,inv4=15075757;
ll n,m;
ll prime[N],v[N],mu[N],tot;
ll sum2[N];
void shai(ll n){
	mu[1]=1;
	for(ll i=2;i<=n;i++){
		if(v[i]==0){
			v[i]=i;prime[++tot]=i;
			mu[i]=-1;
		}
		for(ll j=1;j<=tot;j++){
			if(prime[j]>v[i] || prime[j] > n/i) break;
			v[i*prime[j]]=prime[j];
			if(i % prime[j]==0) mu[i*prime[j]]=0;
			else mu[i*prime[j]]=-mu[i];
		}
	}
}
ll calc(ll n,ll m){
	ll res=0;
	ll l=1,lim=min(n,m);bool Out=0;
	while(l<=lim){
		ll nl=n/l,ml=m/l,r=min(n/nl,m/ml);
		if(r>=lim) r=lim,Out=1;
		ll cnt=nl*(nl+1)%mod*ml%mod*(ml+1)%mod *inv4%mod;
		res=(res+(sum2[r]-sum2[l-1])*cnt%mod)%mod;
		if(Out) break;
		l=r+1;
	}
	return (res%mod+mod)%mod;
}
int main(){
	scanf("%lld%lld",&n,&m);
	shai(max(n,m));
	for(ll i=1;i<=max(n,m);i++) sum2[i]=(sum2[i-1]+i*i%mod*mu[i]%mod)%mod;
	ll ans=0,l=1,lim=min(n,m);
	bool Out=0;
	while(l<=lim){
		ll r=min(n/(n/l),m/(m/l));
		if(r>=lim) r=lim,Out=1;
		ans=(ans+calc(n/l,m/l)*(r*(r+1)%mod-l*(l-1)%mod)%mod*inv2%mod)%mod;
		if(Out) break;
		l=r+1;
	}
	printf("%lld\n",(ans%mod+mod)%mod);
	return 0;
}


- BZOJ2694. Lcm

给定 \(1\le t\le 10^4\)\(1\le n,m\le 4\cdot 10^6\),求 \(i\in[1,n]\,,\,j\in[1,m]\)\(\forall n,n^2 \nmid\gcd(i,j)\) 的数对 \((i,j)\) 个数,即:

\[\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}\mu^2\Big(\gcd(i,j)\Big)\operatorname{lcm}(i,j) \]

直接推式子,把 \(\operatorname{lcm}\) 变成 \(\gcd\),然后枚举 \(\gcd\)

\[\sum\limits_{d=1}^{\min(n,m)} \mu^2(d)\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}[\gcd(i,j)=d]\frac{ij}{d} \]

\(\operatorname{lcm}\) 的处理和上一题很像:

\[\sum\limits_{d=1}^{\min(n,m)} \mu^2(d)\cdot d\sum\limits_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{m}{d}\rfloor}[\gcd(i,j)=1]ij \]

这样子上一题中的 \(f\) 就出来了,省略中间一大堆推导过程:

\[\sum\limits_{d=1}^{\min(n,m)}\Bigg(\mu^2(d)\cdot d \sum\limits_{k=1}^{\min(\lfloor\frac{n}{d}\rfloor,\lfloor\frac{m}{d}\rfloor)}\Big(\mu(k)\cdot k^2\cdot\frac{\lfloor\frac{n}{dk}\rfloor(\lfloor\frac{n}{dk}\rfloor+1)}{2} \cdot \frac{\lfloor\frac{m}{dk}\rfloor(\lfloor\frac{m}{dk}\rfloor+1)}{2}\Big)\Bigg) \]

发现 \(kd\le\min(n,m)\),令 \(T=kd\),经典套路,枚举 \(T\)\(\color{red}\tiny\text{注:在做这道题前我全然不知道这种套路}\)

\[\begin{aligned} &\sum\limits_{T=1}^{\min(n,m)} \frac{\lfloor\frac{n}{T}\rfloor(\lfloor\frac{n}{T}\rfloor+1)}{2} \cdot \frac{\lfloor\frac{m}{T}\rfloor(\lfloor\frac{m}{T}\rfloor+1)}{2} \sum\limits_{k\mid T}\mu(k)\cdot k^2\cdot\frac{T}{k}\cdot\mu^2(\frac{T}{k}) \\=&\sum\limits_{T=1}^{\min(n,m)} \frac{\lfloor\frac{n}{T}\rfloor(\lfloor\frac{n}{T}\rfloor+1)}{2} \cdot \frac{\lfloor\frac{m}{T}\rfloor(\lfloor\frac{m}{T}\rfloor+1)}{2} T\sum\limits_{k\mid T}k\cdot\mu(k)\cdot\mu^2(\frac{T}{k}) \end{aligned}\]

\(f(k)=k\cdot \mu(k)\,,\,g(k)=\mu^2(k)\,,\,h(T)=\sum\limits_{k\mid T}k\cdot\mu(k)\cdot\mu^2(\frac{T}{k})\)

\(f,g\) 为积性函数,又 \(h=f*g\),得 \(h\) 为积性函数。

考虑用线性筛筛出来 \(h\),易得:

\[h(p^k)\begin{cases} 1 &k=0 \\1-p &k=1 \\-p &k=2 \\0 &k>2 \end{cases}\]

这样就可以用线性筛筛出\(h\) 了。

最后对原式进行数论分块,卡卡常就过去了。

提交记录

点击查看代码
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast","inline")
#include<bits/stdc++.h>
#define fr(a) freopen(a,"r",stdin)
#define fw(a) freopen(a,"w",stdout)
#define MP(a,b) make_pair(a,b)
#define DEBUG
using namespace std;
typedef int ll;
const int N=4e6+10,mod=1<<30;
ll T=1;
ll n,m,sum[N];
ll prime[N],v[N],g[N],h[N],tot;
void shai(ll n){
	h[1]=1;
	for(int i=2;i<=n;i++){
		if(v[i]==0){
			prime[++tot]=i;
			v[i]=i;g[i]=i;
		}
		for(int j=1;j<=tot;j++){
			if(prime[j]>v[i]||prime[j]>n/i) break;
			v[i*prime[j]]=prime[j];
			if(i%prime[j]==0) g[i*prime[j]]=g[i]*prime[j];
			else g[i*prime[j]]=prime[j];
		}
	}
	for(int i=2;i<=n;i++){
		if(i==g[i]){
			if(g[i]==v[i]) h[i]=1-v[i];
			else if(g[i]==v[i]*v[i]) h[i]=-v[i];
			else h[i]=0;
		}else h[i]=(h[i/g[i]]*h[g[i]])%mod;
	}
	for(int i=1;i<=n;i++) h[i]=(h[i]*i%mod+h[i-1])%mod,sum[i]=(sum[i-1]+i)%mod;
}
int main(){
	shai(N-10);
	scanf("%d",&T);
	for(int Case=1;Case<=T;Case++){
		scanf("%d%d",&n,&m);
		ll ans=0;
		for(int l=1,r;l<=min(n,m);l=r+1){
            ll nl=n/l,ml=m/l;
			r=min(n/nl,m/ml);
			ans=(ans+sum[nl]*sum[ml] %mod *(h[r]-h[l-1])%mod)%mod;
        }
		printf("%d\n",(ans+mod)%mod);
	}
	return 0;
}

- P4449 于神之怒加强版

给定 \(1\le T\le 2\cdot 10^3\)\(1\le n,m\le 5\cdot 10^6\),和一个固定的 \(1\le \alpha\le 5\cdot 10^6\),求:

\[\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}\gcd(i,j)^\alpha \]

套路!!枚举 \(\gcd\)

\[\sum\limits_{d=1}^{\min(n,m)}d^\alpha \sum\limits_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{m}{d}\rfloor}[\gcd(i,j)=1] \]

莫反拆开:

\[\sum\limits_{d=1}^{\min(n,m)}d^\alpha \sum\limits_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{m}{d}\rfloor}\sum\limits_{k\mid \gcd(i,j)}\mu(k) \]

枚举 \(k\)

\[\sum\limits_{d=1}^{\min(n,m)}d^\alpha \sum\limits_{k=1}^{\min(\lfloor\frac{n}{d}\rfloor,\lfloor\frac{m}{d}\rfloor)}\mu(k)\sum\limits_{i=1}^{\lfloor\frac{n}{dk}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{m}{dk}\rfloor}1 \]

也就是:

\[\sum\limits_{d=1}^{\min(n,m)}d^\alpha \sum\limits_{k=1}^{\min(\lfloor\frac{n}{d}\rfloor,\lfloor\frac{m}{d}\rfloor)}\mu(k) \lfloor\frac{n}{dk}\rfloor\lfloor\frac{m}{dk}\rfloor \]

枚举 \(T=dk\)

\[\sum\limits_{T=1}^{\min(n,m)}\lfloor\frac{n}{T}\rfloor\lfloor\frac{m}{T}\rfloor \sum\limits_{d\mid T}d^\alpha\mu(\frac{T}{d}) \]

后面那个东西其实是 \(id^\alpha*\mu\),显然是积性函数,可以线性筛筛出来\(p\in\mathbb{P},k\ge 1\)):

\[(id^\alpha * \mu)(p^k)=p^{\alpha k}-p^{\alpha(k-1)} \]

筛出来后求个前缀和,然后数论分块即可。

提交记录

点击查看代码
//#pragma GCC optimize(2)
//#pragma GCC optimize(3)
//#pragma GCC optimize("Ofast","inline")
#include<bits/stdc++.h>
#define fr(a) freopen(a,"r",stdin)
#define fw(a) freopen(a,"w",stdout)
#define MP(a,b) make_pair(a,b)
#define DEBUG
using namespace std;
typedef long long ll;
const int N=5e6+10,mod=1e9+7;
ll T=1,k;
ll n,m;
ll prime[N],tot,v[N],mu[N];
ll g[N],f[N];
ll qpow(ll a,ll n){
	ll res=1;
	while(n){
		if(n&1) res=(res*a) %mod;
		a=(a*a)%mod,n>>=1;
	}return res;
}
void shai(ll n){
	f[1]=mu[1]=g[1]=f[1]=1;
	for(int i=2;i<=n;i++){
		if(!v[i]){
			v[i]=i,prime[++tot]=i,mu[i]=-1;
			g[i]=i;
		}
		for(int j=1;j<=tot;j++){
			if(prime[j]>v[i]||prime[j]>n/i) break;
			v[i*prime[j]]=prime[j];
			if(i%prime[j]==0) g[i*prime[j]]=g[i]*prime[j],mu[i*prime[j]]=0;
			else g[i*prime[j]]=prime[j],mu[i*prime[j]]=-mu[i];
		}
	}
	for(int i=2;i<=n;i++){
		if(i==g[i]){
			ll tot=0;
			while(g[i]&&g[i]%v[i]==0) tot++,g[i]/=v[i];
			f[i]=qpow(v[i],k*tot)-qpow(v[i],k*(tot-1));
			f[i]=(f[i]%mod+mod)%mod;
		}else f[i]=(f[i/g[i]]*f[g[i]])%mod;
	}
	for(int i=1;i<=n;i++) f[i]+=f[i-1];
}
int main(){
	scanf("%lld%lld",&T,&k);
	shai(N-10);
	for(int Case=1;Case<=T;Case++){
		scanf("%lld%lld",&n,&m);
		ll ans=0;
		for(int l=1,r;l<=min(n,m);l=r+1){
			ll nl=n/l,ml=m/l;r=min(n/nl,m/ml);
			(ans+=nl*ml%mod*(f[r]-f[l-1])%mod)%=mod;
		}printf("%lld\n",(ans+mod)%mod);
	}
	return 0;
}


- P3327 [SDOI2015] 约数个数和

给定 \(1\le t\le 5\cdot 10^4\)\(1\le n,m\le 5\cdot 10^4\),求:

\[\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}d(ij) \]

其中 \(d(n)\)\(n\) 的约数个数,即 \(\sum\limits_{d\mid n}1\)

蒙结论,蒙出来要求的就是这个东西:

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

原理大概就是:枚举一对互质(为什么不会遗漏我也不知道)的数对 \((i,j)\),满足 \(ab\) 存在因数 \(ij\),且 \(a\le n\,,\,b\le m\) 的数对 \((a,b)\) 的数量显然为 \(\lfloor\frac{n}{i}\rfloor\lfloor\frac{m}{j}\rfloor\)

但是为什么枚举互质\((i,j)\) 就能做到不重不漏,我也不得而知。

接下来这个东西就能做了,用莫反变一下 \([\gcd(i,j)=1]\)

\[\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}\sum\limits_{d\mid \gcd(i,j)}\mu(d)\lfloor\frac{n}{i}\rfloor\lfloor\frac{m}{j}\rfloor \]

套路性地,把 \(d\) 提出去:

\[\sum\limits_{d=1}^{\min(n,m)}\mu(d)\Big(\sum\limits_{i=1}^{n}[d\mid i]\lfloor\frac{n}{i}\rfloor\Big)\Big(\sum\limits_{i=1}^{m}[d\mid i]\lfloor\frac{m}{i}\rfloor\Big) \]

也就是:

\[\sum\limits_{d=1}^{\min(n,m)}\mu(d)\Big(\sum\limits_{i=1}^{\lfloor\frac{n}{d}\rfloor}\lfloor\frac{\lfloor\frac{n}{d}\rfloor}{i}\rfloor\Big)\Big(\sum\limits_{i=1}^{\lfloor\frac{m}{d}\rfloor}\lfloor\frac{\lfloor\frac{m}{d}\rfloor}{i}\rfloor\Big) \]

我们 \(O(n\sqrt {n})\) 预处理一下 \(\sum\limits_{i=1}^{n} \Big\lfloor\dfrac{n}{i}\Big\rfloor\) ,原式最外层整除分块,这个就做完了。

提交记录


附:关于此题正常一些的想法

正常情况下应该蒙出这个结论的:

\[d(nm)=\sum\limits_{i\mid n}\sum\limits_{j\mid m}[\gcd(i,j)=1] \]

我们先把这个证了。

记:

\[nm=\prod\limits_{i=1}^{k}p_i^{a_i+b_i} \,,\, n=\prod\limits_{i=1}^{k}p_i^{a_i}\,,\,m=\prod\limits_{i=1}^{k}p_i^{b_i} \]

我们知道 \(d(nm)=\prod\limits_{i=1}^{k}(a_i+b_i+1)\),我们分别考虑每个质因子。

对于某个质因子 \(p_i\),我们分别考虑等式左右的取法。

对于等式左边,显然取法有 \(a_i+b_i+1\) 种。

对于等式右边,有三类取法:

\[\begin{cases} a_i &n\text{ 中 }p\text{ 取 }1\sim a_i\text{ 个,}m\text{ 中 }p\text{ 取 }0\text{ 个} \\b_i &n\text{ 中 }p\text{ 取 }0\text{ 个,}m\text{ 中 }p\text{ 取 }1\sim b_i\text{ 个} \\ 1&n\text{ 中 }p\text{ 取 }0\text{ 个,}m\text{ 中 }p\text{ 取 }0\text{ 个} \end{cases}\]

加起来一共有 \(a_i+b_i+1\) 种取法。

而每个质因子都是一样的情形,所以总数相同。


有了这个结论,我们正常地推一遍式子:

\[\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}\sum\limits_{x\mid i}\sum\limits_{y\mid j}[\gcd(x,y)=1] \]

直接考虑更换 \(x,y\)\(i,j\) 的枚举顺序:

\[\sum\limits_{x=1}^{n}\sum\limits_{y=1}^{m}\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}[x\mid i][y\mid j][\gcd(x,y)=1] \]

\(\sum\limits_{i=1}^{n}[x\mid i]=\Big\lfloor\dfrac{n}{x}\Big\rfloor\),所以原式:

\[\sum\limits_{x=1}^{n}\sum\limits_{y=1}^{m}\lfloor\dfrac{n}{x}\rfloor\lfloor\dfrac{m}{y}\rfloor[\gcd(x,y)=1] \]

此时已经和我蒙出来的结论一模一样了,这就OK了。

点击查看代码
//#pragma GCC optimize(2)
//#pragma GCC optimize(3)
//#pragma GCC optimize("Ofast","inline")
#include<bits/stdc++.h>
#define fr(a) freopen(a,"r",stdin)
#define fw(a) freopen(a,"w",stdout)
#define MP(a,b) make_pair(a,b)
#define DEBUG
using namespace std;
typedef long long ll;
const int N=5e4+10;
ll TT=1;
ll n,m;
ll prime[N],v[N],mu[N],tot;
ll ji[N];
ll calc(ll n){
	if(ji[n]) return ji[n];
	ll res=0;
	for(int l=1,r;l<=n;l=r+1){
		ll nl=n/l;
		r=n/nl;
		res+=nl * (r-l+1);
	}return ji[n]=res;
}
void shai(ll n){
	mu[1]=1;
	for(ll i=2;i<=n;i++){
		if(v[i]==0){
			v[i]=i;prime[++tot]=i;
			mu[i]=-1;
		}
		for(ll j=1;j<=tot;j++){
			if(prime[j]>v[i] || prime[j] > n/i) break;
			v[i*prime[j]]=prime[j];
			if(i % prime[j]==0) mu[i*prime[j]]=0;
			else mu[i*prime[j]]=-mu[i];
		}
	}
	for(int i=1;i<=n;i++) mu[i]+=mu[i-1],ji[i]=calc(i);
}
int main(){ 
	shai(N-10);
	scanf("%lld",&TT);
	for(int Case=1;Case<=TT;Case++){
		scanf("%lld%lld",&n,&m);
		ll ans=0;
		for(int l=1,r;l<=min(n,m);l=r+1){
			ll nl=n/l,ml=m/l;
			r=min(n/nl,m/ml);
			ans+=(mu[r]-mu[l-1]) * ji[nl]*ji[ml];
		}
		printf("%lld\n",ans);
	}
	return 0;
}


- BZOJ3561. DZY Loves Math VI

给定 \(1 \le n,m\le 5\cdot 10^5\),求:

\[\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}\operatorname{lcm}(i,j) ^{\gcd(i,j)} \]

直接推式子,枚举 \(\gcd\)

\[\sum\limits_{d=1}^{\min(n,m)}\sum\limits_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum\limits_{i=1}^{\lfloor\frac{m}{d}\rfloor}[\gcd(i,j)=1](ijd)^d \]

\(d^d\) 提出去,莫反拆开:

\[\sum\limits_{d=1}^{\min(n,m)}d^d\sum\limits_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum\limits_{i=1}^{\lfloor\frac{m}{d}\rfloor}\sum\limits_{k\mid \gcd(i,j)}\mu(k)(ij)^d \]

套路地,枚举 \(k\)

\[\sum\limits_{d=1}^{\min(n,m)}d^d \sum\limits_{k=1}^{\min(\lfloor\frac{n}{d}\rfloor,\lfloor\frac{m}{d}\rfloor)}\mu(k) \sum\limits_{i=1}^{\lfloor\frac{n}{dk}\rfloor}\sum\limits_{i=1}^{\lfloor\frac{m}{dk}\rfloor}(ik\cdot jk)^d\]

\(k^{2d}\) 提出去,关于 \(i,j\) 的求和分开:

\[\sum\limits_{d=1}^{\min(n,m)}d^d \sum\limits_{k=1}^{\min(\lfloor\frac{n}{d}\rfloor,\lfloor\frac{m}{d}\rfloor)}\mu(k)\cdot k^{2d} (\sum\limits_{i=1}^{\lfloor\frac{n}{dk}\rfloor}i^d) (\sum\limits_{i=1}^{\lfloor\frac{m}{dk}\rfloor}j^d)\]

本来我觉得的这个东西还能再变形,再做,于是想破脑袋想了一个上午没想出来。

但其实,我们分析分析复杂度:

\(d\) 的循环 \(O(n)\)

\(d\)\(k\) 的循环是 \(\dfrac{n}{1}+\dfrac{n}{2}+\dots \dfrac{n}{n}=O(n\log n)\)

如果再算上 \(i\)\(j\) 的循环,那就是 \(\dfrac{n}{1}\log(\dfrac{n}{1})+\dfrac{n}{2}\log(\dfrac{n}{2})+\dots \dfrac{n}{n}\log(\dfrac{n}{n})\),这个东西不超过 \(O(n\log^2 n)\),具体是多少不会算,但其实很小。

因为当 \(d\) 取了 \(d_0\) 时,最内层用到的最大的幂就是 \(\lfloor\frac{n}{d_0}\rfloor ^ d\),于是就可以实时计算 \(1\sim \lfloor\frac{n}{d_0}\rfloor\)\(d\) 次幂,如果在 \(d_0-1\) 时算过了,只需要自乘一下,否则直接用快速幂算。因为每个自然数最多算一次快速幂,这一些预处理的总复杂度就是 \(O(n\log n)\) 的。

预处理之后,可以同时把幂的前缀和算出来,从时间复杂度就到了 \(O(n\log n)\)

所以直接枚举算这个式子就好了……我为什么浪费了一个上午啊啊啊啊啊啊啊啊啊啊啊啊

提交记录

点击查看代码
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast","inline")
#include<bits/stdc++.h>
#define fr(a) freopen(a,"r",stdin)
#define fw(a) freopen(a,"w",stdout)
#define MP(a,b) make_pair(a,b)
#define DEBUG
using namespace std;
typedef long long ll;
const int N=5e5+10,mod=1000000007;
int n,m;
int prime[N],v[N],mu[N],tot;
ll now[N],sum[N];
int tmp[N];
ll qpow(ll a,int n){
	int res=1,stn=n,sta=a;
	while(n){
		if(n&1) res=(1ll*res*a)%mod;
		a=(a*a)%mod,n>>=1;
	}
	return res;
}
void shai(int n){
	mu[1]=1,v[1]=1;
	for(int i=2;i<=n;i++){
		if(v[i]==0){
			v[i]=i;prime[++tot]=i;
			mu[i]=-1;
		}
		for(int j=1;j<=tot;j++){
			if(prime[j]>v[i] || prime[j] > n/i) break;
			v[i*prime[j]]=prime[j];
			if(i % prime[j]==0) mu[i*prime[j]]=0;
			else mu[i*prime[j]]=-mu[i];
		}
	}
}
int main(){
	shai(N-10);
	scanf("%d%d",&n,&m);
	int ans=0;
	for(int d=1;d<=min(n,m);d++){
		int tot=0,lim=min(n/d,m/d);
		for(int i=1;i<=max(n/d,m/d);i++){
			now[i]=((now[i]!=0)?now[i] *i%mod:qpow(i,d))%mod;
			sum[i]=(sum[i-1]+now[i])%mod;
		}
		for(int k=1;k<=lim;k++){
			int cnt1=0,cnt2=0;tmp[1]=1;
			int lim1=n/(d*k),lim2=m/(d*k);
			tot=(tot+ mu[k] * qpow(k,2*d)%mod *sum[lim1]%mod *sum[lim2]%mod )%mod;
		}
		ans=(ans+tot*qpow(d,d)%mod)%mod;
	}printf("%d\n",(ans+mod)%mod);
	return 0;
}

- P5518 [MtOI2019] 幽灵乐团 / 莫比乌斯反演基础练习题

推式子大成!

求:

\[\prod\limits_{i=1}^A\prod\limits_{j=1}^B\prod\limits_{k=1}^C\left(\frac{\operatorname{lcm}(i,j)}{\gcd(i,k)}\right)^{f(type)} \]

其中:

\[\begin{aligned}&f(0)=1\\&f(1)=ijk\\&f(2)=\gcd(i,j,k)\end{aligned} \]

预处理

我们将分子分母分离:

\[\frac{\prod\limits_{i=1}^A\prod\limits_{j=1}^B\prod\limits_{k=1}^C\left(\operatorname{lcm}(i,j)\right)^{f(type)}}{\prod\limits_{i=1}^A\prod\limits_{j=1}^B\prod\limits_{k=1}^C\left(\gcd(i,k)\right)^{f(type)}} \]

也就是:

\[\frac{\prod\limits_{i=1}^A\prod\limits_{j=1}^B\prod\limits_{k=1}^C\left(\frac{ij}{\gcd(i,j)}\right)^{f(type)}}{\prod\limits_{i=1}^A\prod\limits_{j=1}^B\prod\limits_{k=1}^C\left(\gcd(i,k)\right)^{f(type)}} \]

对分子进行子母分离,分母扔下面:

\[\frac{\prod\limits_{i=1}^A\prod\limits_{j=1}^B\prod\limits_{k=1}^C\left(ij\right)^{f(type)}}{\left(\prod\limits_{i=1}^A\prod\limits_{j=1}^B\prod\limits_{k=1}^C\gcd(i,j)^{f(type)}\right)\left(\prod\limits_{i=1}^A\prod\limits_{j=1}^B\prod\limits_{k=1}^C\gcd(i,k)^{f(type)}\right)} \]

关键东西

我们定义一个神奇函数 \(g\),满足:

\[g(x)=\begin{cases}p & x=p^\alpha,\alpha>0\\1 &\text{othercases}\end{cases} \]

这个神奇函数可以 \(O(n)\) 求。

有了神奇函数,我们就可以推导一下这个式子(待会要用到两次,所以扔前头了):

\[\prod\limits_{i=1}^{a}\prod\limits_{j=1}^{b}\gcd(i,j) \]

枚举 \(\gcd\),有:

\[\prod\limits_{d=1}^{\min(a,b)}d^{\sum\limits_{i=1}^{\lfloor\frac{a}{d}\rfloor}\sum\limits_{j=1}^{\lfloor\frac{b}{d}\rfloor}[\gcd(i,j)=1]} \]

莫反拆开往外提:

\[\prod\limits_{d=1}^{\min(a,b)}d^{\sum\limits_{k=1}^{\min(\lfloor\frac{a}{d}\rfloor,\lfloor\frac{b}{d}\rfloor)} \mu(k)\lfloor\frac{a}{dk}\rfloor\lfloor\frac{b}{dk}\rfloor} \]

把上面的求和捋下来,有:

\[\prod\limits_{d=1}^{\min(a,b)}\prod\limits_{k=1}^{\min(\lfloor\frac{a}{d}\rfloor,\lfloor\frac{b}{d}\rfloor)}d^{ \mu(k)\lfloor\frac{a}{dk}\rfloor\lfloor\frac{b}{dk}\rfloor} \]

枚举 \(T=dk\),里面我们不枚举 \(d\) 枚举 \(k\),有:

\[\prod\limits_{T=1}^{\min(a,b)} \prod\limits_{k\mid T}\left(\frac{T}{k}\right) ^{\mu(k)\lfloor\frac{a}{dk}\rfloor\lfloor\frac{b}{dk}\rfloor} \]

我们把底数上的分子 \(T\) 和分母 \(k\) 拆开处理:

\[\prod\limits_{T=1}^{\min(a,b)} \left(\frac{\prod\limits_{k\mid T}T ^{\mu(k)}}{\prod\limits_{k\mid T}k ^{\mu(k)}} \right)^{\lfloor\frac{a}{dk}\rfloor\lfloor\frac{b}{dk}\rfloor} \]

分子

因为底数为 \(T\) 不变,我们把求积符号写在指数上,有:

\[T^{\sum\limits_{k\mid T}\mu(k)} \]

这东西熟悉的不得了,不就是 \(1*\mu=\varepsilon\) 嘛!于是就成了:

\[T^{[T=1]} \]

这玩意一眼顶针,铁定为 \(1\)

分母

我们记 \(f(T)=\prod\limits_{k\mid T}k ^{\mu(k)}\)

没办法拆开了,于是我们考虑一下这玩意的实际含义。

我们对 \(T\) 进行质因数分解,记为 \(T=\prod\limits_{i=1}^{m}p_i^{c_i}\)

我们也对 \(k\) 进行分解:\(k=\prod\limits_{i=1}^{m}p_i^{t_i}\)

注意到当存在 \(t_i>1\) 时,\(\mu(k)=0\),对答案无贡献,于是我们只需考虑指数为 \(0\)\(1\) 的情况;同时我们还可以得到一个推论:\(f(\prod\limits_{i=1}^{m}p_i^{c_i})=f(\prod\limits_{i=1}^{m}p_i)\),其中 \(c_i\ge 1\)

我们对 \(m\) 进行分讨:

\(m=0\)

此时 \(T=1\),有 \(f(T)=1\)

\(m=1\)

此时 \(f(p^\alpha)=f(p)=p^{\mu(p)}=p^{-1}\)

\(m>1\)

我们把 \(f(T)\) 想象成一个分数。

我们我们发现,当指数 \(\mu\)\(1\) 时,这个因数 \(k\) 出现在分子上;否则出现在分母上。

于是我们考虑某一个质因数 \(p\) 分别出现在分子和分母上的数量。

既然 \(p\) 要出现,那么 \(p\) 必须得选,在剩下的 \(m-1\) 个因子中选择一些。

所以分子上的个数就是 \(0+C_{m-1}^{1}+C_{m-1}^{3}+\dots\)

同理,分母上出现的个数是 \(C_{m-1}^{0}+C_{m-1}^{2}+\dots\)

根据一点点组合数学的知识,我们会发现无论 \(m\) 的奇偶性,这俩玩意肯定相等!

既然对于每个质因子,上下的出现次数都相等,那么这一坨玩意就是 \(1\)

\(f(T)=1\)

综上所述,我们发现分子绝对是 \(1\),而分母是这么个玩意,两者一除,就得到了我们开篇提到的神奇函数 \(g\)

所以原式就变成了:

\[\prod\limits_{T=1}^{\min(a,b)} g(T)^{\lfloor\frac{a}{T}\rfloor\lfloor\frac{b}{T}\rfloor} \]

预处理 \(g\) 的前缀积和其逆元,这个就可以一层数论分块搞定!!!

\(type=0\)

\(f(0)=1\) 带入并稍做处理,得:

\[\frac{\left(\prod\limits_{i=1}^A\prod\limits_{j=1}^Bij\right)^C}{\left(\prod\limits_{i=1}^A\prod\limits_{j=1}^B\gcd(i,j)\right)^C\left(\prod\limits_{i=1}^A\prod\limits_{j=1}^C\gcd(i,j)\right)^B} \]

1.分子

\(i\) 提出来(求乘积,故加上 \(B\) 次方):

\[\left(\prod\limits_{i=1}^A\left(i^B\prod\limits_{j=1}^{B}j\right)\right)^C \]

发现内层循环就是 \(B!\) ,即:

\[\left(\prod\limits_{i=1}^A\left(i^BB!\right)\right)^C \]

\(B!\)\(i\) 无关,于是分离开来(记得加上 \(A\) 次方):

\[\left(\left(\prod\limits_{i=1}^{A}i^B\right)\left(B!\right)^A\right)^C \]

观察左边的式子,由于是求乘积,可以把 \(B\) 次方提出来,之后里面就成了 \(A!\) ,即:

\[\left(\left(A!\right)^B\left(B!\right)^A\right)^C \]

很优美了,预处理阶乘后快速幂就行。

2.分母

发现两项非常相似,于是我们令:

\[f_0(a,b,c)=\left(\prod\limits_{i=1}^a\prod\limits_{j=1}^b\gcd(i,j)\right)^c \]

此时分母就成了:

\[f_0(A,B,C)\times f_0(A,C,B) \]

\(f_0\) 里面的东西开篇就推过了,所以有:

\[f_0=\prod\limits_{T=1}^{\min(a,b)} g(T)^{\lfloor\frac{a}{dk}\rfloor\lfloor\frac{b}{dk}\rfloor c} \]

虽然我有统统带回去的毛病,但懒了,不把原式子放出来了!

这样这部分就做完了!

\(type=1\)

\(f(1)=ijk\) 带入,得:

\[\frac{\prod\limits_{i=1}^A\prod\limits_{j=1}^B\prod\limits_{k=1}^C\left(ij\right)^{ijk}}{\left(\prod\limits_{i=1}^A\prod\limits_{j=1}^B\prod\limits_{k=1}^C\gcd(i,j)^{ijk}\right)\left(\prod\limits_{i=1}^A\prod\limits_{j=1}^B\prod\limits_{k=1}^C\gcd(i,k)^{ijk}\right)} \]

分子

把关于 \(k\) 的一维扔出去:

\[\prod\limits_{k=1}^C\left(\prod\limits_{i=1}^A\prod\limits_{j=1}^B\left(ij\right)^{ij}\right)^k \]

发现在 \(k\) 变化时,内部不变,且外层循环的含义就是 \(\sum\limits_{k=1}^Ck\) 个内部的东西乘起来,于是可以变形:

\[\left(\prod\limits_{i=1}^A\prod\limits_{j=1}^B\left(ij\right)^{ij}\right)^{\sum\limits_{k=1}^Ck} \]

求和公式套进去:

\[\left(\prod\limits_{i=1}^A\prod\limits_{j=1}^B\left(ij\right)^{ij}\right)^{\frac{C(C+1)}{2}} \]

接下来,我们先处理内部:

\[\prod\limits_{i=1}^A\prod\limits_{j=1}^B\left(ij\right)^{ij} \]

把幂放进去:

\[\prod\limits_{i=1}^A\prod\limits_{j=1}^Bi^{ij}j^{ij} \]

\(i^{ij}\)\(j^{ij}\) 分开计算(为了使结构更相似,将后面那部分把 \(i\)\(j\) 互换名称):

\[\left(\prod\limits_{i=1}^A\prod\limits_{j=1}^Bi^{ij}\right)\left(\prod\limits_{i=1}^B\prod\limits_{j=1}^Ai^{ij}\right) \]

两部分结构又相同了,我们考虑其中一个:

\[\prod\limits_{i=1}^A\prod\limits_{j=1}^Bi^{ij} \]

可以发现,在 \(j\) 变化时,\(i^i\) 不变,这还是求乘积,可以把关于 \(j\) 的一维扔到指数上:

\[\prod\limits_{i=1}^A(i^i)^{\sum\limits_{j=1}^Bj} \]

指数就成了求和公式,这玩意我们熟悉的不得了,于是:

\[\prod\limits_{i=1}^A(i^i)^{\frac{B(B+1)}{2}} \]

然后一层层往回带,分子部分就变成了:

\[\left(\left(\prod\limits_{i=1}^Ai^i\right)^{\frac{B(B+1)}{2}}\left(\prod\limits_{i=1}^Bi^i\right)^{\frac{A(A+1)}{2}}\right)^{\frac{C(C+1)}{2}} \]

预处理 \(i^i\) 的前缀和,直接算就行了。

分母

发现两项非常相似,于是我们令:

\[f_1(a,b,c)=\prod\limits_{i=1}^a\prod\limits_{j=1}^b\prod\limits_{k=1}^c\gcd(i,j)^{ijk} \]

此时分母就成了:

\[f_1(A,B,C)\times f_1(A,C,B) \]

接下来处理 \(f_1\),先把无关紧要的 \(k\) 提出去,通过和处理分子相同的方法,发现变成了:

\[\left(\prod\limits_{i=1}^a\prod\limits_{j=1}^b\gcd(i,j)^{ij}\right)^{\frac{c(c+1)}{2}} \]

接下来套路处理内部就行了,枚举 \(\gcd\)

\[\left( \prod\limits_{d=1}^{\min(a,b)}d^{ \sum\limits_{i=1}^{\lfloor\frac{a}{d}\rfloor}\sum\limits_{i=1}^{\lfloor\frac{b}{d}\rfloor}[\gcd(i,j)=1]ijd^2 }\right)^{\frac{c(c+1)}{2}}\]

莫反拆开,枚举 \(k\)

\[\left( \prod\limits_{d=1}^{\min(a,b)}\left(d^{d^2}\right)^{ \sum\limits_{k=1}^{\min(\lfloor\frac{a}{d}\rfloor,\lfloor\frac{b}{d}\rfloor)}\mu(k)k^2\sum\limits_{i=1}^{\lfloor\frac{a}{dk}\rfloor}\sum\limits_{i=1}^{\lfloor\frac{b}{dk}\rfloor}ij }\right)^{\frac{c(c+1)}{2}}\]

\(i\)\(j\) 的循环拆开,发现是等差数列求和,于是:

\[\left( \prod\limits_{d=1}^{\min(a,b)}\left(d^{d^2}\right)^{ \sum\limits_{k=1}^{\min(\lfloor\frac{a}{d}\rfloor,\lfloor\frac{b}{d}\rfloor)}\mu(k)k^2 \frac{\lfloor\frac{a}{dk}\rfloor(\lfloor\frac{a}{dk}\rfloor+1)}{2}\frac{\lfloor\frac{b}{dk}\rfloor(\lfloor\frac{b}{dk}\rfloor+1)}{2} }\right)^{\frac{c(c+1)}{2}}\]

预处理一下 \(d^{d^2}\) 的前缀积,和 \(\mu(k)k^2\) 的前缀和,两层数论分块做就完事了。但是,我们有更优的做法!

继续推,把指数上的求和放下来,有:

\[\left( \prod\limits_{d=1}^{\min(a,b)}\prod\limits_{k=1}^{\min(\lfloor\frac{a}{d}\rfloor,\lfloor\frac{b}{d}\rfloor)}d^{{d^2} \mu(k)k^2 \frac{\lfloor\frac{a}{dk}\rfloor(\lfloor\frac{a}{dk}\rfloor+1)}{2}\frac{\lfloor\frac{b}{dk}\rfloor(\lfloor\frac{b}{dk}\rfloor+1)}{2} }\right)^{\frac{c(c+1)}{2}}\]

枚举 \(T=dk\),有:

\[\prod\limits_{T=1}^{\min(a,b)}\left( \prod\limits_{k|T} \left(\frac{T}{k}\right)^{(\frac{T}{k})^2\mu(k)k^2} \right)^{\frac{\lfloor\frac{a}{T}\rfloor(\lfloor\frac{a}{T}\rfloor+1)}{2}\frac{\lfloor\frac{b}{T}\rfloor(\lfloor\frac{b}{T}\rfloor+1)}{2}\frac{c(c+1)}{2}}\]

也就是:

\[\prod\limits_{T=1}^{\min(a,b)}\left( \prod\limits_{k|T} \left(\frac{T}{k}\right)^{\mu(k)T^2} \right)^{\frac{\lfloor\frac{a}{T}\rfloor(\lfloor\frac{a}{T}\rfloor+1)}{2}\frac{\lfloor\frac{b}{T}\rfloor(\lfloor\frac{b}{T}\rfloor+1)}{2}\frac{c(c+1)}{2}}\]

我们找到老熟人了,里面的东西其实就是 \(g(T)^{T^2}\)

于是我们预处理这个东西的前缀积和其逆元,就有:

\[\prod\limits_{T=1}^{\min(a,b)}g(T) ^{T^2\frac{\lfloor\frac{a}{T}\rfloor(\lfloor\frac{a}{T}\rfloor+1)}{2}\frac{\lfloor\frac{b}{T}\rfloor(\lfloor\frac{b}{T}\rfloor+1)}{2}\frac{c(c+1)}{2}}\]

一次数论分块即可。

\(type=2\)

\(f(2)=\gcd(i,j,k)\) 带入,得:

\[\frac{\prod\limits_{i=1}^A\prod\limits_{j=1}^B\prod\limits_{k=1}^C\left(ij\right)^{\gcd(i,j,k)}}{\left(\prod\limits_{i=1}^A\prod\limits_{j=1}^B\prod\limits_{k=1}^C\gcd(i,j)^{\gcd(i,j,k)}\right)\left(\prod\limits_{i=1}^A\prod\limits_{j=1}^B\prod\limits_{k=1}^C\gcd(i,k)^{\gcd(i,j,k)}\right)} \]

我们处理分子分母吧……好累啊……

分子

我们记:

\[f_2(a,b,c)=\prod\limits_{i=1}^a\prod\limits_{j=1}^b\prod\limits_{k=1}^ci^{\gcd(i,j,k)} \]

则分子就是 \(f_2(a,b,c) \times f_2(b,a,c)\)

我们推 \(f_2\)

大头敲开方向要对鲜美鸡汤必须喝掉

枚举\(\gcd\)莫反拆开枚举\(dk\)后数论分块

\[\prod\limits_{d=1}^{\min(a,b,c)} \prod\limits_{i=1}^{\lfloor\frac{a}{d}\rfloor} \prod\limits_{j=1}^{\lfloor\frac{b}{d}\rfloor} \prod\limits_{k=1}^{\lfloor\frac{c}{d}\rfloor} (id)^{d[\gcd(i,j,k)=1]} \]

\[\prod\limits_{d=1}^{\min(a,b,c)} \prod\limits_{i=1}^{\lfloor\frac{a}{d}\rfloor} \prod\limits_{j=1}^{\lfloor\frac{b}{d}\rfloor} \prod\limits_{k=1}^{\lfloor\frac{c}{d}\rfloor} \prod\limits_{t|\gcd(i,j,k)} (id)^{d\mu(t)} \]

\[\prod\limits_{d=1}^{\min(a,b,c)} \prod\limits_{t=1}^{\min(\lfloor\frac{a}{d}\rfloor,\lfloor\frac{b}{d}\rfloor,\lfloor\frac{c}{d}\rfloor)} \prod\limits_{i=1}^{\lfloor\frac{a}{dt}\rfloor} \prod\limits_{j=1}^{\lfloor\frac{b}{dt}\rfloor} \prod\limits_{k=1}^{\lfloor\frac{c}{dt}\rfloor} (idt)^{d\mu(t)} \]

\[\prod\limits_{T=1}^{\min(a,b,c)} \prod\limits_{i=1}^{\lfloor\frac{a}{T}\rfloor} \prod\limits_{j=1}^{\lfloor\frac{b}{T}\rfloor} \prod\limits_{k=1}^{\lfloor\frac{c}{T}\rfloor} (iT)^{\sum\limits_{d|T}d\mu(\frac{T}{d})} \]

蛮好的,有 \(\varphi\) 了:

\[\prod\limits_{T=1}^{\min(a,b,c)} \prod\limits_{i=1}^{\lfloor\frac{a}{T}\rfloor} \prod\limits_{j=1}^{\lfloor\frac{b}{T}\rfloor} \prod\limits_{k=1}^{\lfloor\frac{c}{T}\rfloor} (iT)^{\varphi(T)} \]

\(i\)\(T\) 分开,有:

\[\prod\limits_{T=1}^{\min(a,b,c)} T^{\varphi(T)\lfloor\frac{a}{T}\rfloor\lfloor\frac{b}{T}\rfloor\lfloor\frac{c}{T}\rfloor} \left(\lfloor\frac{a}{T}\rfloor!\right)^{\lfloor\frac{b}{T}\rfloor\lfloor\frac{c}{T}\rfloor\varphi(T)} \]

一次数论分块即可。

分母

我们令:

\[f_3(a,b,c)=\prod\limits_{i=1}^a\prod\limits_{j=1}^b\prod\limits_{k=1}^c\gcd(i,j)^{\gcd(i,j,k)} \]

那么分母就是:\(f_3(A,B,C) \times f_3(A,C,B)\)

\(f_3\) 即可,这东西折磨了我好久,直到我把两次拆开放到一起……

枚举 \(d=\gcd(i,j,k)\),有:

\[\prod\limits_{d=1}^{\min(a,b,c)} \prod\limits_{i=1}^{\lfloor\frac{a}{d}\rfloor} \prod\limits_{j=1}^{\lfloor\frac{b}{d}\rfloor} \prod\limits_{k=1}^{\lfloor\frac{c}{d}\rfloor} (d\gcd(i,j))^{d[\gcd(i,j,k)=1]} \]

拆成 \(\mu\),放到底数:

\[\prod\limits_{d=1}^{\min(a,b,c)} \prod\limits_{i=1}^{\lfloor\frac{a}{d}\rfloor} \prod\limits_{j=1}^{\lfloor\frac{b}{d}\rfloor} \prod\limits_{k=1}^{\lfloor\frac{c}{d}\rfloor} \prod\limits_{t|\gcd(i,j,k)} (d\gcd(i,j))^{d\mu(t)} \]

\(t\) 移出去:

\[\prod\limits_{d=1}^{\min(a,b,c)} \prod\limits_{t=1}^{\min(\lfloor\frac{a}{d}\rfloor,\lfloor\frac{b}{d}\rfloor,\lfloor\frac{c}{d}\rfloor)} \prod\limits_{i=1}^{\lfloor\frac{a}{dt}\rfloor} \prod\limits_{j=1}^{\lfloor\frac{b}{dt}\rfloor} \prod\limits_{k=1}^{\lfloor\frac{c}{dt}\rfloor} (dt\gcd(i,j))^{d\mu(t)} \]

发现 \(k\) 这一维可以缩水到指数上了,顺便把变量名 \(t\) 换成 \(k\),有:

\[\prod\limits_{d=1}^{\min(a,b,c)} \prod\limits_{k=1}^{\min(\lfloor\frac{a}{d}\rfloor,\lfloor\frac{b}{d}\rfloor,\lfloor\frac{c}{d}\rfloor)} \prod\limits_{i=1}^{\lfloor\frac{a}{dk}\rfloor} \prod\limits_{j=1}^{\lfloor\frac{b}{dk}\rfloor} (dk\gcd(i,j))^{d\mu(k)\lfloor\frac{c}{dk}\rfloor} \]

然后我们枚举 \(T=dk\),有:

\[\prod\limits_{T=1}^{\min(a,b,c)} \prod\limits_{i=1}^{\lfloor\frac{a}{T}\rfloor} \prod\limits_{j=1}^{\lfloor\frac{b}{T}\rfloor} (T\gcd(i,j))^{\lfloor\frac{c}{dk}\rfloor\sum\limits_{d|T}d\mu(\frac{T}{d})} \]

得,\(\varphi\) 出来了,这一步我退出来乐死了

\[\prod\limits_{T=1}^{\min(a,b,c)} \prod\limits_{i=1}^{\lfloor\frac{a}{T}\rfloor} \prod\limits_{j=1}^{\lfloor\frac{b}{T}\rfloor} (T\gcd(i,j))^{\lfloor\frac{c}{dk}\rfloor\varphi(T)} \]

分成两部分,就是:

\[\prod\limits_{T=1}^{\min(a,b,c)} T^{\varphi(T)\lfloor\frac{a}{T}\rfloor\lfloor\frac{b}{T}\rfloor} \left(\prod\limits_{i=1}^{\lfloor\frac{a}{T}\rfloor} \prod\limits_{j=1}^{\lfloor\frac{b}{T}\rfloor} \gcd(i,j)\right)^{\lfloor\frac{c}{dk}\rfloor\varphi(T)} \]

后者,又出现了我们文章最开头推的式子,于是就成了:

\[\prod\limits_{T=1}^{\min(a,b,c)} T^{\varphi(T)\lfloor\frac{a}{T}\rfloor\lfloor\frac{b}{T}\rfloor} \left( \prod\limits_{D=1}^{\min(\lfloor\frac{a}{T}\rfloor,\lfloor\frac{b}{T}\rfloor)} g(D)^{\lfloor\frac{a}{DT}\rfloor\lfloor\frac{a}{DT}\rfloor} \right)^{\lfloor\frac{c}{dk}\rfloor\varphi(T)} \]

两层数论分块,终于,搞!定!

这b题终于让我写!!完!!了!!

提交记录

点击查看代码
//#pragma GCC optimize(2)
//#pragma GCC optimize(3)
//#pragma GCC optimize("Ofast","inline")
#include<bits/stdc++.h>
#define fr(a) freopen(a,"r",stdin)
#define fw(a) freopen(a,"w",stdout)
#define MP(a,b) make_pair(a,b)
#define DEBUG
using namespace std;
typedef long long ll;
const int N=1e5+10;
ll T=1,mod,pmod;
ll A,B,C,ans1,ans2,ans3;
ll prime[N],v[N],tot,mu[N],smu[N],smu2[N],phi[N];
ll jie[N],invj[N],tphi[N],invtphi[N],sphi[N];
ll slf[N],invslf[N];
ll gm[N],invgm[N],invsmu[N];
ll nai[N],sn[N],invsn[N],sn2[N],invsn2[N];
ll qpow(ll a,ll n){
	n=(n%pmod +pmod)%pmod;
	a %=mod;
	ll res=1;
	while(n){
		if(n&1) res=(res*a)%mod;
		a=(a*a)%mod;n>>=1;
	}return res;
}
void shai(ll n){
	mu[1]=phi[1]=1;
	for(ll i=2;i<=n;i++){
		if(v[i]==0){
			v[i]=i;prime[++tot]=i;
			mu[i]=-1;phi[i]=i-1;
		}for(ll j=1;j<=tot;j++){
			if(prime[j]>v[i]||prime[j]>n/i) break;
			v[i*prime[j]]=prime[j];
			if(i%prime[j]==0) mu[i*prime[j]]=0,phi[i*prime[j]]=phi[i]*(prime[j]);
			else mu[i*prime[j]]=-mu[i],phi[i*prime[j]]=phi[i]*(prime[j]-1);
		}
	}
}
void init(ll n){
	jie[0]=invj[0]=slf[0]=invslf[0]=1;
	gm[0]=invgm[0]=1;
	tphi[0]=invtphi[0]=1;
	pmod=mod-1;
	for(ll i=1;i<=n;i++){
		jie[i]=(jie[i-1]*i)%mod;
		invj[i]=qpow(jie[i],mod-2);
		slf[i]=slf[i-1] * qpow(i,i)%mod;
		invslf[i]=qpow(slf[i],mod-2);
		smu[i]=(smu[i-1]+mu[i])%pmod;
		smu2[i]=(smu2[i-1] + mu[i] * i * i%pmod)%pmod;
		gm[i]=gm[i-1] * qpow(i,mu[i])%mod;
		invgm[i]=qpow(gm[i],-1);
		tphi[i]=tphi[i-1] * qpow(i,phi[i]) %mod;
		invtphi[i]=qpow(tphi[i],-1);
		sphi[i] = (sphi[i-1] + phi[i]) %pmod;
		nai[i]=1;
	}
	for(int i=1;i<=tot;i++){
		ll now=prime[i];
		if(now>n) break;
		while(now<n){
			nai[now]=prime[i];
			now *= prime[i];
		}
	}
	sn[0]=invsn[0]=sn2[0]=invsn2[0]=1;
	for(int i=1;i<=n;i++){
		sn[i]=(sn[i-1] * nai[i])%mod;
		invsn[i]=qpow(sn[i],-1);
		sn2[i]= sn2[i-1] * qpow(nai[i],1ll * i*i%pmod) %mod;
		invsn2[i]=qpow(sn2[i],-1);
	}
}
ll f32(ll a,ll b){
	ll res=1,lim=min(a,b);
	for(ll l=1,r;l<=lim;l=r+1){
		ll ad=a/l,bd=b/l;r=min(a/ad,b/bd);
		(res *= qpow(sn[r] * invsn[l-1] %mod ,ad * bd%pmod) )%=mod;
	}return res;
}
ll f0(ll a,ll b,ll c){
	return qpow(f32(a,b),c);
}
void work1(){	
	ll ans=qpow(qpow(jie[A],B)*qpow(jie[B],A)%mod,C),tot=1;
	(ans*=qpow(f0(A,B,C) * f0(A,C,B) %mod,mod-2)) %=mod;
	ans1=(ans+mod)%mod;
}
ll f1(ll a,ll b,ll c){
	ll res=1,lim=min(a,b);
	for(ll l=1,r;l<=lim;l=r+1){
		ll ad=a/l,bd=b/l;r=min(a/ad,b/bd);
		ll zhi=(ad*(ad+1)/2) %pmod *( (bd*(bd+1)/2) %pmod) %pmod;
		(res *= qpow(sn2[r] * invsn2[l-1] %mod ,zhi) )%=mod;
	}
	res= qpow(res,c*(c+1)/2);
	return res;
}
void work2(){
	ll zi=1,ans=qpow(f1(A,B,C) * f1(A,C,B)%mod,mod-2);
	zi=qpow(slf[A],B*(B+1)/2) * qpow(slf[B],A*(A+1)/2) %mod;
	(ans *=qpow(zi,C*(C+1)/2)) %=mod;
	ans2=(ans+mod)%mod;
}
ll f2(ll a,ll b,ll c){
	ll res=1,limd=min(min(a,b),c);
	for(ll ld=1,rd;ld<=limd;ld=rd+1){
		ll ad=a/ld,bd=b/ld,cd=c/ld;
		rd=min(min(a/ad,b/bd),c/cd);
		(res *= qpow(gm[rd] * invgm[ld-1]%mod,ad*bd%pmod*cd%pmod) )%=mod;
		ll tmp=qpow(jie[ad],bd*cd%pmod);
		(res *= qpow(tmp,(smu[rd]-smu[ld-1])%pmod))%=mod;
	}return res;
}
ll f2_5(ll a,ll b,ll c){
	ll res=1,lim=min(min(a,b),c);
	for(ll l=1,r;l<=lim;l=r+1){
		ll at=a/l,bt=b/l,ct=c/l;
		r=min(min(a/at,b/bt),c/ct);
		(res *= qpow(tphi[r] * invtphi[l-1]%mod , at * bt %pmod *ct %pmod))%=mod;
		ll tmp=qpow(jie[at],bt*ct%pmod);
		(res *= qpow(tmp,(sphi[r] - sphi[l-1]) %pmod))%=mod;
	}return res;
}
ll f3(ll a,ll b,ll c){
	ll limt=min(min(a,b),c),res=1;
	for(int lt=1,rt;lt<=limt;lt=rt+1){
		ll at=a/lt,bt=b/lt,ct=c/lt;
		rt=min(min(a/at,b/bt),c/ct);
		ll tmp=tphi[rt] * invtphi[lt-1] %mod;
		(res *= qpow(tmp,at * bt%pmod * ct%pmod) )%=mod;
		tmp=qpow(f32(at,bt) %mod,ct) %mod;
		(res *= qpow(tmp,(sphi[rt] - sphi[lt-1]) %pmod) )%=mod;
	}return res;
}
void work3(){
	ll zi=f2_5(A,B,C) * f2_5(B,A,C) %mod;
	ll mu=f3(A,B,C) * f3(A,C,B)%mod;
	ans3=(zi*qpow(mu,-1)%mod+mod)%mod;
	return;
}
int main(){
	scanf("%lld%lld",&T,&mod);
	shai(N-10);
	init(N-10);
	for(int Case=1;Case<=T;Case++){
		scanf("%lld%lld%lld",&A,&B,&C);
		work1();work2();
		work3();
		printf("%lld %lld %lld\n",ans1,ans2,ans3);
	}
	return 0;
}


- P1587 [NOI2016] 循环之美

给定 \(n,m,k\),求分子不大于 \(n\),分母不大于 \(m\),在 \(k\) 进制下为纯循环小数的最简分数个数。

我们有一个不会证的结论:当分母和进制互质,分子和分母互质时,这个分数是 \(k\) 进制下的纯循环小数。

于是就成了求以下东西:

\[\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}[\gcd(i,j)=1][\gcd(j,k)=1] \]

推式子,对后一项莫反拆开:

\[\sum\limits_{d|k}\mu(d)\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{\lfloor\frac{m}{d}\rfloor}[\gcd(i,jd)=1] \]

显然,我们有 \(\gcd(a,b)=1,\gcd(a,c)=1\Longleftrightarrow\gcd(a,bc)=1\)

故我们发现后面是一个规模缩小的原问题。

我们设:

\[f(n,m,k)=\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}[\gcd(i,j)=1][\gcd(j,k)=1] \]

于是我们有递推式:

\[f(n,m,k)=\sum\limits_{d|k}\mu(d)f(\left\lfloor\frac{m}{d}\right\rfloor,n,d) \]

直接开搜就行了。

终止状态:

  1. \(n=0\)\(m=0\) 时,\(f(n,m,k)=0\)

  2. \(k=1\) 时,\(f(n,m,k)=\sum\limits_{d=1}^{\min(n,m)}\mu(d)\left\lfloor\dfrac{n}{d}\right\rfloor\left\lfloor\dfrac{m}{d}\right\rfloor\),基本推式子没的说。

所以我们用杜教筛处理 \(\mu\) 前缀和,数论分块算上面的东西,并加入以下剪枝:

  1. 我们提前预处理 \(k\) 的“所有因数”的所有因数,显然空间复杂度是 \(O(k^2)\) 的,可以接受,此时枚举 \(d\) 的复杂度直接从 \(1000\) 降到了 \(64\),很大的优化。

  2. \(\mu(d)=0\) 时,不往下搜,显然,这个优化更大。

加入这两个剪枝后就能顺利过此题了。

提交记录

特别鸣鸣鸣鸣鸣鸣鸣鸣谢 Qcfff,基本上思路全都是抄他的呜呜呜。

P3704 [SDOI2017] 数字表格

给定 \(n,m\),求:

\[\prod\limits_{i=1}^{n}\prod\limits_{j=1}^{m}f_{\gcd(i,j)} \]

这不乱做?

\[\prod\limits_{d=1}^{\min(n,m)}\prod\limits_{k=1}^{\min(\lfloor\frac{n}{d}\rfloor,\lfloor\frac{m}{d}\rfloor)}f_d^{\mu(k)\lfloor\frac{n}{dk}\rfloor\lfloor\frac{m}{dk}\rfloor} \]

枚举 \(T=dk\)

\[\prod\limits_{T=1}^{\min(n,m)}\Bigg(\prod\limits_{d\mid T}f_d^{\mu(\frac{T}{d})}\Bigg)^{\lfloor\frac{n}{T}\rfloor\lfloor\frac{m}{T}\rfloor} \]

里面的东西预处理,\(O(n\sqrt n)\),因为指数只会是 \(0,1,-1\)

然后做完了!整除分块。水紫真舒服

提交记录

P2257 YY的GCD

求:

\[\sum\limits_{p\in\mathbb{P}}\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{m}[\gcd(i,j)=p] \]

莫个反先:

\[\sum\limits_{p\in\mathbb P}\sum\limits_{d=1}^{\min(\lfloor\frac{n}{p}\rfloor,\lfloor\frac{m}{p}\rfloor)}\mu(d)\lfloor\frac{n}{pd}\rfloor\lfloor\frac{m}{pd}\rfloor \]

枚举 \(T=pd\)

\[\sum\limits_{T=1}^{\min(n,m)}\lfloor\frac{n}{T}\rfloor\lfloor\frac{m}{T}\rfloor\sum\limits_{p\in\mathbb P,p\mid T}\mu(\frac{T}{p}) \]

后面的可以预处理。求个前缀和。做完了。

提交记录

双倍经验 & 提交记录

P1891 疯狂 LCM

挺好玩。求:

\[\sum\limits_{i=1}^{n}{\rm lcm}(i,n) \]

先拆一下:

\[\sum\limits_{i=1}^{n}\frac{i\times n}{\gcd(i,n)} \]

枚举 \(\gcd\)

\[n\sum\limits_{d\mid n}\frac{1}{d}\sum\limits_{i=1}^{\frac{n}{d}}d\cdot i[\gcd(i,\frac{n}{d})=1] \]

发现好玩的事:\(d\) 约掉了。我们记 \(f(n)=\sum\limits_{i=1}^{n} i[\gcd(i,n)=1]\),于是原式变成:

\[n\sum\limits_{d\mid n}f(\frac{n}{d})=n\sum\limits_{d\mid n}f(d) \]

我们先处理 \(f(n)\):莫反拆开:

\[f(n)=\sum\limits_{i=1}^{n}i\sum\limits_{k\mid \gcd(i,n)}\mu(k) \]

枚举 \(k\)

\[f(n)=\sum\limits_{k\mid n}\mu(k)\sum\limits_{i=1}^{\frac{n}{k}}ik \]

也就是:

\[f(n)=\sum\limits_{k\mid n}\mu(k)k\frac{\frac{n}{k}(\frac{n}{k}+1)}{2}=\sum\limits_{k\mid n}\mu(k)n(\frac{n}{k}+1)\frac{1}{2} \]

然后 \(f\) 可以 \(O(n\log n)\) 预处理吧!我们再看原式:

\[n\sum\limits_{d\mid n}f(d) \]

也可以 \(O(n\log n)\) 预处理吧!

于是我们 \(O(n\log n)\) 预处理,\(O(1)\) 查询。做完了!

提交记录

posted @ 2024-01-27 16:27  一匹大宝羊  阅读(48)  评论(0编辑  收藏  举报