我是靠谱客的博主 高大绿茶,最近开发中收集的这篇文章主要介绍YbtOJ#943-平方约数【莫比乌斯反演,平衡规划】正题,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

正题

题目链接:http://www.ybtoj.com.cn/contest/122/problem/3


题目大意

S ( i ) S(i) S(i)表示 i i i的约数个数, Q Q Q次询问给出 n , m n,m n,m
∑ a = 1 n ∑ b = 1 m S ( a 2 ) × S ( b 2 ) × S ( a × b ) sum_{a=1}^nsum_{b=1}^mS(a^2)times S(b^2)times S(atimes b) a=1nb=1mS(a2)×S(b2)×S(a×b)

1 ≤ Q ≤ 1 0 4 , 1 ≤ n , m ≤ 2 × 1 0 5 1leq Qleq 10^4,1leq n,mleq 2times 10^5 1Q104,1n,m2×105


解题思路

前面的推式子挺套路的
首先我们要搞定 S ( n 2 ) S(n^2) S(n2)这个东西,一个经典的结论就是 S ( n × m ) = ∑ i ∣ n ∑ j ∣ m [ g c d ( i , j ) = 1 ] S(ntimes m)=sum_{i|n}sum_{j|m}[gcd(i,j)=1] S(n×m)=injm[gcd(i,j)=1]。莫反一下就有
S ( a × b ) = ∑ d ∣ ( a × b ) μ ( d ) ∑ i × d ∣ a ∑ j × d ∣ b 1 S(atimes b)=sum_{d|(atimes b)}mu(d)sum_{itimes d|a}sum_{jtimes d|b}1 S(a×b)=d(a×b)μ(d)i×daj×db1
所以就有
S ( n 2 ) = ∑ d ∣ n μ ( d ) S ( n d ) 2 S(n^2)=sum_{d|n}mu(d)S(frac{n}{d})^2 S(n2)=dnμ(d)S(dn)2
用线性筛筛出前面的 S S S,然后 O ( n log ⁡ n ) O(nlog n) O(nlogn)求出 h ( n ) = S ( n 2 ) h(n)=S(n^2) h(n)=S(n2)

然后化一下式子
∑ a = 1 n ∑ b = 1 m h ( a ) × h ( b ) ∑ i ∣ a ∑ j ∣ b [ g c d ( i , j ) = 1 ] sum_{a=1}^nsum_{b=1}^mh(a)times h(b)sum_{i|a}sum_{j|b}[gcd(i,j)=1] a=1nb=1mh(a)×h(b)iajb[gcd(i,j)=1]
∑ d = 1 μ ( d ) ( ∑ d ∣ i ∑ i ∣ a h ( a ) ) ( ∑ d ∣ j ∑ j ∣ b h ( b ) ) sum_{d=1}mu(d)(sum_{d|i}sum_{i|a}h(a))(sum_{d|j}sum_{j|b}h(b)) d=1μ(d)(diiah(a))(djjbh(b))
∑ d = 1 μ ( d ) ( ∑ d ∣ a S ( a d ) h ( a ) ) ( ∑ d ∣ b S ( b d ) h ( b ) ) sum_{d=1}mu(d)(sum_{d|a}S(frac{a}{d})h(a))(sum_{d|b}S(frac{b}{d})h(b)) d=1μ(d)(daS(da)h(a))(dbS(db)h(b))

然后就好像没得化简了,先处理出 F ( d , n ) = ∑ i = 1 n h ( i × d ) S ( i ) F(d,n)=sum_{i=1}^nh(itimes d)S(i) F(d,n)=i=1nh(i×d)S(i)

发现 d d d很大的时候后面那个东西的取值就很小,但是 d d d很多,需要快速处理。

设定一个分界值 T T T,每次小于 T T T的部分我们就暴力用 F F F数组计算,大于 T T T的部分我们预处理出一个
G ( d , i , j ) = ∑ x = T + 1 d F ( i ) F ( j ) μ ( d ) G(d,i,j)=sum_{x=T+1}^dF(i)F(j)mu(d) G(d,i,j)=x=T+1dF(i)F(j)μ(d)
然后整除分块计算。

这里的 k k k N 2 3 N^{frac{2}{3}} N32会平均一些,时间复杂度 O ( n 4 3 + Q n 2 3 ) O(n^{frac{4}{3}}+Qn^{frac{2}{3}}) O(n34+Qn32)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#define ll long long
using namespace std;
const ll N=2e5+10,P=1<<30;
ll q,n,m,cnt,pri[N],mu[N],S[N],sg[N],g[N],o[N];
vector<int>f[N],d[N];
bool v[N];
void prime(){
	mu[1]=sg[1]=1;
	for(ll i=2;i<N;i++){
		if(!v[i])pri[++cnt]=i,mu[i]=-1,g[i]=2,sg[i]=2;
		for(ll j=1;j<=cnt&&i*pri[j]<N;j++){
			v[i*pri[j]]=1;
			if(i%pri[j]==0){
				g[i*pri[j]]=g[i]+1;
				sg[i*pri[j]]=sg[i]/g[i]*g[i*pri[j]];
				break;
			}
			mu[i*pri[j]]=-mu[i];g[i*pri[j]]=2;
			sg[i*pri[j]]=sg[i]*sg[pri[j]];
		}
	}
	for(ll i=1;i<N;i++)
		for(ll j=i;j<N;j+=i)
			(S[j]+=sg[j/i]*sg[j/i]*mu[i]%P)%=P;
	return;
}
signed main()
{
	freopen("math.in","r",stdin);
	freopen("math.out","w",stdout);
	prime();
	scanf("%lld",&q);ll lim=2e5;
	ll T=(ll)pow(lim,2.0/3.0)+1;
	f[0].resize(lim+1);
	for(ll i=1;i<=lim;i++){
		f[i].push_back(0); 
		for(ll j=1;j<=lim/i;j++){
			ll tmp=f[i][j-1];
			f[i].push_back((tmp+S[i*j]*sg[j])%P);
		}
	}
	d[T].resize((lim/T)*(lim/T)+1);
	for(ll i=T+1;i<=lim;i++){
		ll p=lim/i;
		d[i].resize(p*p+1);
		for(ll j=1,sum=0;j<=lim/i;j++)
			for(ll k=j;k<=lim/i;k++)
				d[i][(j-1)*p+k]=(d[i-1][(j-1)*o[i-1]+k]+f[i][j]*f[i][k]*mu[i])%P;
		o[i]=p;
	}
	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+=1ll*f[i][n/i]*f[i][m/i]*mu[i]%P)%=P;
		for(ll l=T+1,r;l<=n;l=r+1){
			r=min(n/(n/l),m/(m/l));
			(ans+=d[r][(n/l-1)*o[r]+m/l]-d[l-1][(n/l-1)*o[l-1]+m/l])%=P;
		}
		printf("%lldn",(ans+P)%P);
	}
	return 0;
}

最后

以上就是高大绿茶为你收集整理的YbtOJ#943-平方约数【莫比乌斯反演,平衡规划】正题的全部内容,希望文章能够帮你解决YbtOJ#943-平方约数【莫比乌斯反演,平衡规划】正题所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(58)

评论列表共有 0 条评论

立即
投稿
返回
顶部