【莫比乌斯反演】[SDOI2018]旧试题

题目

∑ i = 1 A ∑ j = 1 B ∑ k = 1 C d ( i , j , k ) \sum_{i=1}^A\sum_{j=1}^B\sum_{k=1}^Cd(i,j,k) i=1Aj=1Bk=1Cd(i,j,k)

题解

前置: d ( i , j , k ) = ∑ a ∣ i ∑ b ∣ j ∑ c ∣ k [ g c d ( a , b ) = = 1 ] [ g c d ( a , c ) = = 1 ] [ g c d ( b , c ) = = 1 ] d(i,j,k)=\sum_{a\mid i}\sum_{b\mid j}\sum_{c\mid k}[gcd(a,b)==1][gcd(a,c)==1][gcd(b,c)==1] d(i,j,k)=aibjck[gcd(a,b)==1][gcd(a,c)==1][gcd(b,c)==1]
推柿子环节:
∑ i = 1 A ∑ j = 1 B ∑ k = 1 C d ( i , j , k ) ∑ i = 1 A ∑ j = 1 B ∑ k = 1 C ∑ a ∣ i ∑ b ∣ j ∑ c ∣ k [ g c d ( a , b ) = = 1 ] [ g c d ( a , c ) = = 1 ] [ g c d ( b , c ) = = 1 ] ∑ a = 1 A ∑ b = 1 B ∑ c = 1 C [ g c d ( a , b ) = = 1 ] [ g c d ( a , c ) = = 1 ] [ g c d ( b , c ) = = 1 ] ∑ i = 1 ⌊ A a ⌋ ∑ j = 1 ⌊ B b ⌋ ∑ k = 1 ⌊ C c ⌋ ∑ a = 1 A ∑ b = 1 B ∑ c = 1 C ⌊ A a ⌋ ⌊ B b ⌋ ⌊ C c ⌋ [ g c d ( a , b ) = = 1 ] [ g c d ( a , c ) = = 1 ] [ g c d ( b , c ) = = 1 ] ∑ a = 1 A ∑ b = 1 B ∑ c = 1 C ⌊ A a ⌋ ⌊ B b ⌋ ⌊ C c ⌋ ∑ d 1 ∣ g c d ( a , b ) μ ( d 2 ) ∑ d 2 ∣ g c d ( a , c ) μ ( d 2 ) ∑ d 3 ∣ g c d ( b , c ) μ ( d 3 ) \sum_{i=1}^A\sum_{j=1}^B\sum_{k=1}^Cd(i,j,k)\\ \sum_{i=1}^A\sum_{j=1}^B\sum_{k=1}^C\sum_{a\mid i}\sum_{b\mid j}\sum_{c\mid k}[gcd(a,b)==1][gcd(a,c)==1][gcd(b,c)==1]\\ \sum_{a=1}^A\sum_{b=1}^B\sum_{c=1}^C[gcd(a,b)==1][gcd(a,c)==1][gcd(b,c)==1]\sum_{i=1}^{\lfloor \frac A a\rfloor}\sum_{j=1}^{\lfloor \frac B b\rfloor}\sum_{k=1}^{\lfloor \frac C c\rfloor}\\ \sum_{a=1}^A\sum_{b=1}^B\sum_{c=1}^C{\lfloor \frac A a\rfloor}{\lfloor \frac B b\rfloor}{\lfloor \frac C c\rfloor}[gcd(a,b)==1][gcd(a,c)==1][gcd(b,c)==1]\\ \sum_{a=1}^A\sum_{b=1}^B\sum_{c=1}^C{\lfloor \frac A a\rfloor}{\lfloor \frac B b\rfloor}{\lfloor \frac C c\rfloor}\sum_{d_1\mid gcd(a,b)}\mu(d_2)\sum_{d_2\mid gcd(a,c)}\mu(d_2)\sum_{d_3\mid gcd(b,c)}\mu(d_3) i=1Aj=1Bk=1Cd(i,j,k)i=1Aj=1Bk=1Caibjck[gcd(a,b)==1][gcd(a,c)==1][gcd(b,c)==1]a=1Ab=1Bc=1C[gcd(a,b)==1][gcd(a,c)==1][gcd(b,c)==1]i=1aAj=1bBk=1cCa=1Ab=1Bc=1CaAbBcC[gcd(a,b)==1][gcd(a,c)==1][gcd(b,c)==1]a=1Ab=1Bc=1CaAbBcCd1gcd(a,b)μ(d2)d2gcd(a,c)μ(d2)d3gcd(b,c)μ(d3)
重 要 部 分 : ∑ d 1 = 1 m i n ( A , B ) μ ( d 1 ) ∑ d 2 = 1 m i n ( A , C ) μ ( d 2 ) ∑ d 3 = 1 m i n ( B , C ) μ ( d 3 ) ∑ a = 1 ⌊ A l c m ( d 1 , d 2 ) ⌋ ⌊ A a × l c m ( d 1 , d 2 ) ⌋ ∑ b = 1 ⌊ B l c m ( d 1 , d 3 ) ⌋ ⌊ B b × l c m ( d 1 , d 3 ) ⌋ ∑ c = 1 ⌊ C l c m ( d 2 , d 3 ) ⌋ ⌊ C c × l c m ( d 2 , d 3 ) ⌋ 重要部分:\\ \sum_{d1=1}^{min(A,B)}\mu(d_1) \sum_{d2=1}^{min(A,C)}\mu(d_2) \sum_{d3=1}^{min(B,C)}\mu(d_3) \sum_{a=1}^{\lfloor \frac A {lcm(d_1,d_2)}\rfloor}{\lfloor \frac A {a\times lcm(d_1,d_2)}\rfloor} \sum_{b=1}^{\lfloor \frac B {lcm(d_1,d_3)}\rfloor}{\lfloor \frac B {b\times lcm(d_1,d_3)}\rfloor} \sum_{c=1}^{\lfloor \frac C {lcm(d_2,d_3)}\rfloor}{\lfloor \frac C {c\times lcm(d_2,d_3)}\rfloor} d1=1min(A,B)μ(d1)d2=1min(A,C)μ(d2)d3=1min(B,C)μ(d3)a=1lcm(d1,d2)Aa×lcm(d1,d2)Ab=1lcm(d1,d3)Bb×lcm(d1,d3)Bc=1lcm(d2,d3)Cc×lcm(d2,d3)C
千万注意枚举 d 1 , d 2 , d 3 d1,d2,d3 d1,d2,d3时,对应 a , b , c a,b,c a,b,c能取得值为 l c m ( d 1 , d 2 ) ∗ ( 1 − > ⌊ A l c m ( d 1 , d 2 ) ⌋ ) lcm(d_1,d_2)*(1->\lfloor \frac A {lcm(d_1,d_2)}\rfloor) lcm(d1,d2)(1>lcm(d1,d2)A)而不是 d 1 d 2 ∗ ( 1 − > ⌊ A d 1 d 2 ⌋ ) d_1d_2*(1->\lfloor \frac A {d_1d_2}\rfloor) d1d2(1>d1d2A)

  • f ( x ) = ∑ i = 1 x ⌊ x i ⌋ f(x)=\sum_{i=1}^x{\lfloor \frac x i\rfloor} f(x)=i=1xix我选择数论分块求单个,很神奇地可以过。似乎可以转换成约数个数前缀和,然而我不会推。。。

最后关键部分
∑ d 1 = 1 m i n ( A , B ) ∑ d 2 = 1 m i n ( A , C ) ∑ d 3 = 1 m i n ( B , C ) μ ( d 1 ) μ ( d 2 ) μ ( d 3 ) f ( ⌊ A l c m ( d 1 , d 2 ) ⌋ ) f ( ⌊ B l c m ( d 1 , d 3 ) ⌋ ) f ( ⌊ C l c m ( d 2 , d 3 ) ⌋ ) \sum_{d1=1}^{min(A,B)}\sum_{d2=1}^{min(A,C)}\sum_{d3=1}^{min(B,C)} \mu(d_1)\mu(d_2)\mu(d_3) f({\lfloor \frac A {lcm(d_1,d_2)}\rfloor}) f({\lfloor \frac B {lcm(d_1,d_3)}\rfloor}) f({\lfloor \frac C {lcm(d_2,d_3)}\rfloor}) d1=1min(A,B)d2=1min(A,C)d3=1min(B,C)μ(d1)μ(d2)μ(d3)f(lcm(d1,d2)A)f(lcm(d1,d3)B)f(lcm(d2,d3)C)
鬼知道怎么的,就需要建图,就是要找 ( d 1 , d 2 , d 3 ) (d_1,d_2,d_3) (d1,d2,d3)三元组累加贡献
其中 μ ( d ) = 0 ∣ ∣ l c m ( d 1 , d 2 ) > A ∣ ∣ l c m ( d 1 , d 3 ) > B ∣ ∣ l c m ( d 2 , d 3 ) > C \mu(d)=0||lcm(d_1,d_2)>A||lcm(d_1,d_3)>B||lcm(d_2,d_3)>C μ(d)=0lcm(d1,d2)>Alcm(d1,d3)>Blcm(d2,d3)>C这样的是没有贡献的
将两个合法的 d d d连边,最后找三元环累加即可
当然不可能 O ( n 2 ) O(n^2) O(n2)建边,所以经检验总边数最大为760741,自己想什么奇怪的方法建,最后参见某位巨佬的三元环计数方法, O ( m m ) O(m\sqrt m) O(mm )累加贡献
还要注意一件事:我们除了三元环还要枚举 ( d , d , d ) (d,d,d) (d,d,d)和其中两个 d d d相同的贡献
于是肝了一天,有(chao)了以下代码

#include<bits/stdc++.h>
#define ll long long
#define re register
using namespace std;
const int N=2e5+10,M=2e5,E=2e6+10;
const ll mod=1e9+7;
int gcd(int x,int y){return !x?y:gcd(y%x,x);}
ll bt[N];int bs,ls[N];
ll miu[N],f[N];
int z[N],p;
bool vis[N];
void Sieve()
{
	miu[1]=1;
	for(re int i=2;i<=M;++i)
	{
		if(!vis[i])z[++p]=i,miu[i]=-1;
		for(re int j=1;j<=p&&i*z[j]<=M;++j)
		{
			vis[i*z[j]]=1;
			if(i%z[j]==0)break;
			miu[i*z[j]]=-miu[i];
		}
	}
	for(re int i=1;i<=M;++i)
	if(miu[i])bt[++bs]=i,ls[i]=bs;
	
	for(re int i=1;i<=M;++i)
	for(re int l=1,r;l<=i;l=r+1)
	{
		r=i/(i/l);
		f[i]=(f[i]+(ll)(r-l+1)*(i/l)%mod)%mod;
	}
}
int n;
int A,B,C;
int head[N],nex[E],to[E],val[E],tot;
void build(int u,int v,int w)
{
	tot++;nex[tot]=head[u];to[tot]=v;val[tot]=w;head[u]=tot;
}
struct Road{
	int x,y,z;
}road[E];int all;
int rd[N];
int vs[N];
void init()
{
	for(re int i=1;i<=tot;++i)nex[i]=to[i]=val[i]=0;tot=0;
	for(re int i=1;i<=n;++i)rd[i]=head[i]=0;
}
ll work()
{
	ll ans=0;all=0;
	n=max(max(A,B),C);
	for(re int i=1;i<=bs&&bt[i]<=n;++i)
	{
		for(re int j=1;j<=bs&&bt[i]*bt[j]<=n;++j)
		{
			if(!miu[bt[i]*bt[j]])continue;
			for(re int k=j+1;k<=bs&&bt[i]*bt[j]*bt[k]<=n;++k)
			{
				if(!miu[bt[i]*bt[k]]||gcd(bt[j],bt[k])!=1)continue;
				int x=ls[bt[i]*bt[j]],y=ls[bt[i]*bt[k]],z=bt[i]*bt[j]*bt[k];
				build(x,y,z);build(y,x,z);
				rd[x]++;rd[y]++;road[++all]={x,y,z};
			}
		}
	}
	int AB=min(A,B);
	for(re int i=1;i<=bs&&bt[i]<=AB;++i)
	{
		int u=bt[i];
		for(re int j=head[i];j;j=nex[j])
		{
			int v=bt[to[j]],w=val[j];
			ans=(ans+miu[u]*miu[u]*miu[v]*f[A/w]*f[B/u]%mod*f[C/w]%mod+mod)%mod;
			ans=(ans+miu[u]*miu[v]*miu[u]*f[A/u]*f[B/w]%mod*f[C/w]%mod+mod)%mod;
			ans=(ans+miu[u]*miu[v]*miu[v]*f[A/w]*f[B/w]%mod*f[C/v]%mod+mod)%mod;
		}
	}
	int ABC=min(min(A,B),C);
	for(re int i=1;i<=bs&&bt[i]<=ABC;++i)
	{
		int u=bt[i];
		ans=(ans+miu[u]*miu[u]*miu[u]*f[A/u]*f[B/u]%mod*f[C/u]%mod+mod)%mod;
	}
	//
	init();
	for(re int i=1;i<=all;++i)
	if(rd[road[i].x]>=rd[road[i].y])build(road[i].x,road[i].y,road[i].z);
	else							build(road[i].y,road[i].x,road[i].z);
	for(re int u=1;u<=bs&&bt[u]<=n;++u)
	{
		for(re int j=head[u];j;j=nex[j])vs[to[j]]=val[j];
		for(re int j=head[u];j;j=nex[j])
		{
			int v=to[j];
			for(re int k=head[v];k;k=nex[k])
			{
				int uu=to[k];if(!vs[uu])continue;
				//u->(j)v->(k)uu->()
				int a=val[j],b=val[k],c=vs[uu];
				ll fw=f[A/a]*(f[B/b]*f[C/c]%mod+f[B/c]*f[C/b]%mod)%mod
					 +f[A/b]*(f[B/a]*f[C/c]%mod+f[B/c]*f[C/a]%mod)%mod
					 +f[A/c]*(f[B/a]*f[C/b]%mod+f[B/b]*f[C/a]%mod)%mod;
				fw%=mod;
				ans=(ans+miu[bt[u]]*miu[bt[v]]*miu[bt[uu]]*fw+mod)%mod;
			}
		}
		for(re int j=head[u];j;j=nex[j])vs[to[j]]=0;
	}return ans;
}
int main()
{
	int T;Sieve();
	scanf("%d",&T);
	while(T--)
	{
		init();
		scanf("%d%d%d",&A,&B,&C);
		printf("%lld\n",work());
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值