P4240-毒瘤之神的考验【莫比乌斯反演,平衡规划】

正题

题目链接:https://www.luogu.com.cn/problem/P4240


题目大意

Q Q Q组数据给出 n , m n,m n,m
∑ i = 1 n ∑ j = 1 m φ ( i × j ) \sum_{i=1}^n\sum_{j=1}^m\varphi(i\times j) i=1nj=1mφ(i×j)
1 ≤ Q ≤ 1 0 4 , 1 ≤ n , m ≤ 1 0 5 1\leq Q\leq 10^4,1\leq n,m\leq 10^5 1Q104,1n,m105


解题思路

首先需要知道的结论就是
φ ( i × j ) = φ ( i ) φ ( j ) g c d ( i , j ) φ ( g c d ( i , j ) ) \varphi(i\times j)=\varphi(i)\varphi(j)\frac{gcd(i,j)}{\varphi(gcd(i,j))} φ(i×j)=φ(i)φ(j)φ(gcd(i,j))gcd(i,j)

然后推一下式子
∑ i = 1 n ∑ j = 1 m φ ( i ) φ ( j ) g c d ( i , j ) φ ( g c d ( i , j ) ) \sum_{i=1}^n\sum_{j=1}^m\varphi(i)\varphi(j)\frac{gcd(i,j)}{\varphi(gcd(i,j))} i=1nj=1mφ(i)φ(j)φ(gcd(i,j))gcd(i,j)
∑ d = 1 n d φ ( d ) ∑ d ∣ i n ∑ d ∣ j m φ ( i ) φ ( j ) [ g c d ( i , j ) = d ] \sum_{d=1}^n\frac{d}{\varphi(d)}\sum_{d|i}^n\sum_{d|j}^m\varphi(i)\varphi(j)[gcd(i,j)=d] d=1nφ(d)ddindjmφ(i)φ(j)[gcd(i,j)=d]
然后莫反一波
∑ d = 1 n d φ ( d ) ∑ z ∣ d n μ ( z d ) ∑ z ∣ i n ∑ z ∣ j m φ ( i ) φ ( j ) \sum_{d=1}^n\frac{d}{\varphi(d)}\sum_{z|d}^n\mu(\frac{z}{d})\sum_{z|i}^n\sum_{z|j}^m\varphi(i)\varphi(j) d=1nφ(d)dzdnμ(dz)zinzjmφ(i)φ(j)
提出 z z z
∑ z = 1 n ( ∑ z ∣ i n φ ( i ) ∑ z ∣ j m φ ( j ) ) ∑ d ∣ z μ ( z d ) d φ ( d ) \sum_{z=1}^n(\sum_{z|i}^n\varphi(i)\sum_{z|j}^m\varphi(j))\sum_{d|z}\mu(\frac{z}{d})\frac{d}{\varphi(d)} z=1n(zinφ(i)zjmφ(j))dzμ(dz)φ(d)d
后面那个很好求,线性筛然后 O ( n log ⁡ n ) O(n\log n) O(nlogn)处理就好了,并且设为 g i g_i gi,后面需要用到。但是前面那个比较麻烦,而且我们好像就推不动了。

这其实是一个挺经典的 t r a c k track track的,考虑平衡规划。设定一个 T T T,对于小于等于 T T T的部分我们暴力算,对于大于 T T T的部分我们考虑预处理。

f i , j = ∑ j ∣ x i φ ( x ) f_{i,j}=\sum_{j|x}^i\varphi(x) fi,j=jxiφ(x),然后再设一个 h i , j , k h_{i,j,k} hi,j,k
h i , j , k = ∑ x = T + 1 f i , j × f i , k × g i h_{i,j,k}=\sum_{x=T+1}f_{i,j}\times f_{i,k}\times g_{i} hi,j,k=x=T+1fi,j×fi,k×gi
这个可以用一个前缀和 O ( n n T 2 ) O(n\frac{n}{T}^2) O(nTn2)的做到。

然后大于 T T T的部分我们就可以用上面预处理的 h h h+整除分块做到 O ( n ) O(\sqrt n) O(n )了。

总共的时间复杂度是 O ( n n + n T 2 + Q ( T + n ) ) O(n\sqrt n+nT^2+Q(T+\sqrt n)) O(nn +nT2+Q(T+n ))
T T T设为 n 2 3 n^{\frac{2}{3}} n32就是 O ( n n + n 4 3 + Q n 2 3 ) O(n\sqrt n+n^{\frac{4}{3}}+Qn^{\frac{2}{3}}) O(nn +n34+Qn32)了。


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
#define ll long long
using namespace std;
const ll N=1e5+10,P=998244353;
ll Q,n,m,cnt,pri[N],inv[N],mu[N],phi[N],g[N],o[N];
bool v[N];vector<ll> f[N],h[N];
void prime(){
	phi[1]=mu[1]=1;
	for(ll i=2;i<N;i++){
		if(!v[i])pri[++cnt]=i,phi[i]=i-1,mu[i]=-1;
		for(ll j=1;j<=cnt&&i*pri[j]<N;j++){
			v[i*pri[j]]=1;
			if(i%pri[j]==0){
				phi[i*pri[j]]=phi[i]*pri[j];
				break;
			}
			phi[i*pri[j]]=phi[i]*(pri[j]-1);
			mu[i*pri[j]]=-mu[i];
		}
	}
	inv[1]=1;
	for(ll i=2;i<N;i++)
		inv[i]=P-(P/i)*inv[P%i]%P;
	for(ll i=1;i<N;i++)
		for(ll j=i;j<N;j+=i)
			(g[j]+=inv[phi[i]]*i%P*mu[j/i])%=P;
	return;
}
signed main()
{
	prime();
	ll L=1e5,T=(ll)pow(L,2.0/3.0)+1;
	f[0].resize(L+1);
	for(ll i=1;i<=L;i++){
		f[i].resize(L/i+1);
		for(ll j=1;j<=L/i;j++)
			f[i][j]=(f[i][j-1]+phi[i*j])%P;
	}
	h[T].resize((L/T)*(L/T)+1);
	for(ll i=T+1;i<=L;i++){
		ll p=L/i;h[i].resize(p*p+1);
		for(ll j=1;j<=p;j++)
			for(ll k=1;k<=p;k++)
				h[i][(j-1)*p+k]=(h[i-1][(j-1)*o[i-1]+k]+f[i][j]*f[i][k]%P*g[i]%P)%P;
		o[i]=p;
	}
	scanf("%lld",&Q);
	while(Q--){
		scanf("%lld%lld",&n,&m);
		if(n>m)swap(n,m);ll ans=0;
		for(ll i=1;i<=min(T,n);i++)
			(ans+=f[i][n/i]*f[i][m/i]%P*g[i]%P)%=P;
		for(ll l=T+1,r;l<=n;l=r+1){
			r=min(n/(n/l),m/(m/l));
			(ans+=h[r][(n/l-1)*o[r]+m/l]-h[l-1][(n/l-1)*o[l-1]+m/l])%=P;
		}
		printf("%lld\n",(ans+P)%P);
	}
	return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值