Special topic of Mobius inversion (Advanced)

Posted by noisenet on Tue, 25 Jan 2022 08:15:56 +0100

51nod 1675 sequence transformation

We construct two new sequences \ (A,B \)
\(A_x=a_{b_x},B_x=b_{a_x}\)
Then the condition given by the topic is equivalent to
\(gcd(i,j)==1,A_ i=B_ Number of \ (I, J \) of J \)
Let \ (f(x) \) represent \ (GCD (i,j) = = x, a_ i=B_ Number of \ (i,j \) of J \)
Let \ (F(x) \) represent \ (x|gcd (i,j), a_ i=B_ Number of \ (i,j \) of J \)
So what we want is \ (f(1) \)
Then \ (F(n)=\sum_{n|d}f(d)\)
According to Mobius multiple inversion formula
\(f(n)=\sum_{n|d}F(d)\mu(\frac{d}{n})\)
Let's consider how to find \ (F(x) \)
It is observed that \ (x|i,x|j \), that is, \ (i,j \) are multiples of \ (x \)
Then we can first add \ (A_i \) where the subscript is A multiple of \ (x \) to the bucket in the A sequence, and then we enumerate the positions where the subscript is A multiple of \ (x \) in \ (B \) to see how many \ (B_j \) are in the bucket. The complexity is harmonic series \ (O(nlogn) \)

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e5+7;
int a[N],b[N];
int mu[N],prime[N],tot=0;
int v[N];
void init(int n)
{
	mu[1]=1;
	for(int i=2;i<=n;i++)
	{
		if(!v[i])
		{
			v[i]=i;
			prime[++tot]=i;
			mu[i]=-1;
		}
		for(int j=1;j<=tot;j++)
		{
			if(prime[j]>v[i]||i*prime[j]>n) break;
			v[i*prime[j]]=prime[j];
			if(i%prime[j]==0)
			{
				mu[i*prime[j]]=0;
				break;
			}
			else mu[i*prime[j]]=mu[i]*mu[prime[j]];
		}
	}
}
int A[N],B[N];
int n;
int t[N];
int main()
{
	freopen("seq.in","r",stdin);
	freopen("seq.out","w",stdout);
	cin>>n;
	init(n);
	for(int i=1;i<=n;i++)
	scanf("%d",&a[i]);
	for(int i=1;i<=n;i++)
	scanf("%d",&b[i]);
	for(int i=1;i<=n;i++)
	A[i]=a[b[i]];
	for(int i=1;i<=n;i++)
	B[i]=b[a[i]];
	long long ans=0;
	for(int i=1;i<=n;i++)
	{
		LL F=0;
		for(int j=i;j<=n;j+=i)
		t[A[j]]++;
		for(int j=i;j<=n;j+=i)
		F+=t[B[j]];
		for(int j=i;j<=n;j+=i)
		t[A[j]]--;
		ans+=1ll*mu[i]*F;
	} 
	cout<<ans;
	return 0;
}

SDOI2014 data table

Let \ (f(x) \) represent the number of factors of \ (x \)
Then the question is asked Q times and \ (n,m,a \) is given each time
seek

\[\sum_{i=1}^n\sum_{j=1}^mf(gcd(i,j)),f(gcd(i,j))\leq a \]

Simplification

\[\sum_{i=1}^n\sum_{j=1}^m\sum_{d|i,d|j,f(d)\leq a}[gcd(i,j)==d]f(d) \]

\[\sum_{d=1}^n[f(d)\leq a]\sum_{d|i}^n\sum_{d|j}^m[gcd(i,j)==d]f(d) \]

\[\sum_{d=1,f(d)\leq a}^nf(d)\sum_{i=1}^{\lfloor \frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor \frac{m}{d}\rfloor}[gcd(i,j)==1] \]

\[\sum_{d=1,f(d)\leq a}^nf(d)\sum_{i=1}^{\lfloor \frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor \frac{m}{d}\rfloor}\sum_{k|i,k|j}\mu(k) \]

\[\sum_{d=1,f(d)\leq a}^nf(d)\sum_{k=1}^{\lfloor \frac{n}{d}\rfloor}\mu(k)\sum_{i=1}^{\lfloor \frac{n}{dk}\rfloor}\sum_{j=1}^{\lfloor \frac{m}{dk}\rfloor}1 \]

\[\sum_{d=1,f(d)\leq a}^nf(d)\sum_{k=1}^{\lfloor \frac{n}{d}\rfloor}\mu(k)\lfloor \frac{n}{dk}\rfloor\lfloor \frac{m}{dk}\rfloor \]

\[\sum_{T=1}^n\lfloor \frac{n}{T}\rfloor\lfloor \frac{m}{T}\rfloor \sum_{d|T,f(d)\leq a}^nf(d)\mu(\frac{T}{d}) \]

Where \ (f \) is an integral function, which can be preprocessed by line sieve
If there is no limit of a, just divide the block directly \ (O(\sqrt n) \)
However, there are \ (a \) restrictions, so some \ (d \) are illegal
We consider taking queries offline and sorting them by \ (a \)
This can ensure that if a number makes a contribution at a certain time, its contribution will not be eliminated. If it is shared equally, it will be \ (O(n) \)
So we sort all the numbers by \ (f \), and then we enumerate the newly added \ (d \)
Then enumerate his multiples \ (T \) and add the contribution of \ (d to T \). Because the division of blocks requires prefix and, we use the tree array to add the contribution
Time complexity \ (O(q\sqrt n \log n+n\log^2 n) \)

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL N = 1e5+10;
LL t[N],g[N],f[N];
LL v[N],prime[N],tot=0;
LL w[N];
LL mu[N]; 
bool cmp(LL x,LL y)
{
	return f[x]<f[y];
}
const LL mod = (1ll<<31); 
void init(LL n)
{
	f[1]=1;
	mu[1]=1;
	for(LL i=2;i<=n;i++)
	{
		if(!v[i])
		{
			prime[++tot]=i;
			v[i]=i;
			f[i]=1+i;
			g[i]=i;
			t[i]=1+i;
			mu[i]=-1;
		}
		for(LL j=1;j<=tot;j++)
		{
			if(v[i]<prime[j]||i*prime[j]>n) break;
			v[i*prime[j]]=prime[j];
			if(i%prime[j]==0)
			{
				mu[i*prime[j]]=0;
				g[i*prime[j]]=g[i]*prime[j];
				t[i*prime[j]]=t[i]+g[i*prime[j]];
				f[i*prime[j]]=f[i]/t[i]*t[i*prime[j]];
				break;
			}
			else 
			{
				mu[i*prime[j]]=mu[i]*mu[prime[j]];
				g[i*prime[j]]=prime[j];
				t[i*prime[j]]=prime[j]+1;
				f[i*prime[j]]=f[i]*f[prime[j]];
			}
		}
	}
	for(LL i=1;i<=n;i++)
	w[i]=i;
	sort(w+1,w+n+1,cmp);
}
LL tree[N];
LL lowbit(LL x)
{
	return x&(-x);
}
void add(LL x,LL v)
{
	for(LL i=x;i<=1e5;i+=lowbit(i))
	tree[i]+=v;
}
LL ask(LL x)
{
	LL res=0;
	for(LL i=x;i;i-=lowbit(i))
	res+=tree[i];
	return res;
}
struct Query
{
	LL n,m,a;
	LL id;
}q[N];
bool cmp2(Query a,Query b)
{
	return a.a<b.a;
}
LL ans[N];
LL calc(LL n,LL m)
{
	if(n>m) swap(n,m);
	LL l=1,r;
	LL ans=0;
	for(;l<=n;l=r+1)
	{
		r=min(n/(n/l),m/(m/l));
		ans=(ans+(ask(r)-ask(l-1))*1ll*(n/l)*(m/l)); 
	}
	return ans;
}
int main()
{
	freopen("test.in","r",stdin);
	freopen("test.out","w",stdout);
	init(1e5);
	LL Q;
	cin>>Q;
	for(LL i=1;i<=Q;i++)
	scanf("%lld %lld %lld",&q[i].n,&q[i].m,&q[i].a);
	for(LL i=1;i<=Q;i++)
	q[i].id=i;
	sort(q+1,q+Q+1,cmp2);
	LL j=1;
	for(LL i=1;i<=Q;i++)
	{
		while(f[w[j]]<=q[i].a&&j<=1e5)
		{
			for(LL k=w[j];k<=1e5;k+=w[j])
			{
				add(k,f[w[j]]*mu[k/w[j]]);	
			}
			j++;
		}
		ans[q[i].id]=calc(q[i].n,q[i].m);
	}
	for(LL i=1;i<=Q;i++)
	printf("%lld\n",ans[i]%mod);
	return 0;
}

BZOJ3561 DZY Loves Math VI

\[\sum_{i=1}^n\sum_{j=1}^mlcm(i,j)^{gcd(i,j)} \]

\[=\sum_{i=1}^n\sum_{j=1}^m(\frac{ij}{gcd(i,j)})^{gcd(i,j)} \]

\[=\sum_{i=1}^n\sum_{j=1}^m\sum_{d|i,d|j}(\frac{ij}{d})^{d}[gcd(i,j)==d] \]

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

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

\[=\sum_{d=1}^nd^d\sum_{i=1}^{\lfloor \frac{n}{d} \rfloor}i^d\sum_{j=1}^{\lfloor \frac{n}{d} \rfloor}j^d\sum_{k|i,k|j}\mu(k) \]

\[=\sum_{d=1}^nd^d\sum_{k=1}^{\lfloor \frac{n}{d} \rfloor}\mu(k)k^{2d}\sum_{i=1}^{\lfloor \frac{n}{dk} \rfloor}i^d\sum_{j=1}^{\lfloor \frac{n}{dk} \rfloor}j^d \]

Set \ (S(x)=\sum_{i=1}^xi^d\)
Then the preprocessing can achieve \ (O(nlogn) \)
Then enumerate \ (d \) and \ (k \), classical harmonic series \ (O(nlogn) \)

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 5e5+7;
LL mu[N];
int prime[N],tot=0;
int v[N];
void init(int n)
{
	mu[1]=1;
	for(int i=2;i<=n;i++)
	{
		if(!v[i])
		{
			v[i]=i;
			mu[i]=-1;
			prime[++tot]=i;
		}
		for(int j=1;j<=tot;j++)
		{
			if(v[i]<prime[j]||i*prime[j]>n) break;
			v[i*prime[j]]=prime[j];
			if(i%prime[j]==0)
			{
				mu[i*prime[j]]=0;
				break;
			}
			else mu[i*prime[j]]=mu[i]*mu[prime[j]];
		}
	}
}
const int mod = 1e9+7;
LL Pow(LL a,LL b)
{
	LL res=1;
	while(b)
	{
		if(b&1) res=1ll*res*a%mod;
		a=1ll*a*a%mod;
		b>>=1;
	}
	return res;
}
LL pw[N];
LL S[N];
int main()
{
	freopen("test.in","r",stdin);
	freopen("test.out","w",stdout);
	int n,m;
	cin>>n>>m;
	if(n>m) swap(n,m);
	init(n);
	LL ans=0;
	for(int i=1;i<=m;i++)
	pw[i]=1;
	for(int d=1;d<=n;d++)
	{
		LL p=Pow(d,d);
		int I=(n/d),J=(m/d);
		for(int i=1;i<=J;i++)
		{
			pw[i]=1ll*pw[i]*i%mod;
			S[i]=(S[i-1]+pw[i])%mod;
		}
		for(int x=1;x<=I;x++)
		ans=(ans+1ll*p*mu[x]%mod*pw[x]%mod*pw[x]%mod*S[I/x]%mod*S[J/x]%mod)%mod;
 	} 
 	cout<<ans;
	return 0;
}

[BZOJ3309]DZY Loves Math

\[\sum_{i=1}^n\sum_{j=1}^mf(gcd(i,j)) \]

\(f(x) \) represents the highest power of the prime factor of \ (x \)

\[\sum_{i=1}^n\sum_{j=1}^m\sum_{d|i,d|j}[gcd(i,j)==d]f(d) \]

\[\sum_{d=1}^nf(d)\sum_{i=1}^{\lfloor \frac{n}{d} \rfloor}\sum_{j=1}^{\lfloor \frac{m}{d}\rfloor}[gcd(i,j)==1] \]

\[\sum_{d=1}^nf(d)\sum_{i=1}^{\lfloor \frac{n}{d} \rfloor}\sum_{j=1}^{\lfloor \frac{m}{d}\rfloor}\sum_{k|i,k|j}\mu(k) \]

\[\sum_{d=1}^nf(d)\sum_{k=1}^{\lfloor \frac{n}{d} \rfloor}\mu(k)\sum_{i=1}^{\lfloor \frac{n}{dk} \rfloor}\sum_{j=1}^{\lfloor \frac{m}{dk}\rfloor}1 \]

\[\sum_{d=1}^nf(d)\sum_{k=1}^{\lfloor \frac{n}{d} \rfloor}\mu(k)\lfloor \frac{n}{dk} \rfloor\lfloor \frac{m}{dk}\rfloor \]

\[\sum_{T=1}^n\lfloor \frac{n}{T} \rfloor\lfloor \frac{m}{T}\rfloor\sum_{d|T}^nf(d)\mu(\frac{T}{d}) \]

The latter can obviously be calculated by \ (O(nlogn) \), but \ (n \) is \ (10 ^ 7 \)
Let's examine the properties of the following functions
Let \ (f(T)=a \), \ (t \) have \ (k \) heterogeneous factors, and the exponent of \ (t has q \) factors is equal to \ (a \)
Let's investigate when \ (\ mu(T/d) \) is not 0
That is \ (f(d) \) is \ (a \) or \ (a-1 \), otherwise \ (\ mu(T/d) \) has a factor index greater than 2, which is 0
Let's discuss it by category
When \ (q==k \)
That is, the exponent of all factors is \ (a \)
Then if \ (f(d)==a \)
Then the contribution is \ (a\sum_{f(d)==a}\mu(T/d) \)
If I locations in the enumeration \ (d \) are \ (a \), then \ (k-i \) locations are \ (a-1 \), then only that \ (k-i \) location in \ (T\d \) has a value
That is \ (\ sum {I = 1} ^ KC _k ^ I (- 1) ^ {k-i} \), there is at least one \ (a \) because \ (f(d)=a \), so enumeration starts from I. according to the binomial theorem, \ (= (1+(-1))^k-(-1)^k=a(-1)^{k+1} \)
Then if \ (f(d)==a-1 \)
Then all positions in d must be \ (a-1 \), and the answer is \ ((a-1)(-1)^k \)
So when the total answer to \ (k==q \) is \ (a(-1)^{k+1}+(a-1)(-1)^k=(-1)^k \)
Similarly, if \ (K \ GEQ \), you can calculate that the answer is 0
So we draw the following conclusions
If the exponent of not all positions in \ (t \) is a, then \ (F(T)=0 \)
If \ (t \) has an odd number of heterogeneous factors, then \ (F(T)=1 \)
Otherwise \ (F(T)=-1 \)
We can use a linear sieve to sun out the highest power of each number, the number of different quality factors, and the power of the smallest prime factor. The power is equal to the number of prime factors of the highest power, and then we can find the \ (F \) of each number. Then we just need to find the prefix and divide the blocks
Attention card often

SDOI2017 digital table

Strange topic
seek

\[\prod_{i=1}^n\prod_{j=1}^mf(gcd(i,j)) \]

\(f(x) \) is the Fibonacci sequence
Start inversion

\[\prod_{i=1}^n\prod_{j=1}^m\prod_{d|i,d|j}[gcd(i,j)==d]f(d) \]

\[\prod_{d=1}^nf(d)^{\sum{i=1}^n\sum{j=1}^m[gcd(i,j)==d]} \]

\[\prod_{d=1}^nf(d)^{\sum_{i=1}^{\lfloor \frac{n}{d} \rfloor}\sum_{j=1}^{\lfloor \frac{m}{d} \rfloor}[gcd(i,j)==1]} \]

Look at the denominator alone, we know

\[\sum_{i=1}^{\lfloor \frac{n}{d} \rfloor}\sum_{j=1}^{\lfloor \frac{m}{d} \rfloor}[gcd(i,j)==1]=\sum_{k=1}^{\lfloor \frac{n}{d} \rfloor}\mu(k)\lfloor \frac{n}{dk} \rfloor\lfloor \frac{m}{dk} \rfloor \]

Favorite, enumeration \ (T \)

\[\prod_{T=1}^{n}\prod_{d|T}f(d)^{\mu(\frac{T}{d})\lfloor \frac{n}{T} \rfloor\lfloor \frac{m}{T} \rfloor} \]

that is

\[\prod_{T=1}^{n}\prod_{d|T}(f(d)^{\mu(\frac{T}{d})})^{\lfloor \frac{n}{T} \rfloor\lfloor \frac{m}{T} \rfloor} \]

Set \ (F(n)=\prod_{d|n}f(d)^{\mu(\frac{n}{d})} \), which can be preprocessed with \ (O(n\log n) \)
be

\[ans=\prod_{T=1}^{n}\prod_{d|T}F(T)^{\lfloor \frac{n}{T} \rfloor\lfloor \frac{m}{T} \rfloor} \]

Because there are only \ (O(\sqrt n) \) changes in the index according to the division of blocks, the prefix product of preprocessing \ (F \) can be divided into blocks

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL N = 1e6+7;
const LL mod = 1e9+7;
LL mu[N],v[N],prime[N];
LL tot=0;
LL Pow(LL a,LL b)
{
	LL res=1;
	while(b)
	{
		if(b&1) res=1ll*res*a%mod;
		a=1ll*a*a%mod;
		b>>=1;
	}
	return res;
} 
LL inv[N];
LL f[N];
LL F[N];
void init(LL n)
{
	f[0]=0;
	f[1]=1;
	inv[1]=1;
	for(LL i=2;i<=n;i++)
	{
		f[i]=(f[i-1]+f[i-2])%mod;
		inv[i]=Pow(f[i],mod-2);
	}
	mu[1]=1;
	for(LL i=2;i<=n;i++)
	{
		if(!v[i])
		{
			v[i]=i;
			prime[++tot]=i;
			mu[i]=-1;
		}
		for(LL j=1;j<=tot;j++)
		{
			if(prime[j]>v[i]||i*prime[j]>n) break;
			v[i*prime[j]]=prime[j];
			if(i%prime[j]==0)
			{
				mu[i*prime[j]]=0;
				break;
			}
			else mu[i*prime[j]]=mu[i]*mu[prime[j]];
		}
	}
	for(LL i=1;i<=n;i++)
	F[i]=1;
	for(LL d=1;d<=n;d++)
	{
		for(LL T=d;T<=n;T+=d)
		{
			LL val=(mu[T/d]==1?f[d]:(mu[T/d]==-1?inv[d]:1ll));
			F[T]=1ll*F[T]*val%mod;
		}
	}
	F[0]=1;
	for(LL i=1;i<=n;i++)
	F[i]=1ll*F[i-1]*F[i]%mod;
}
int main()
{
	freopen("test.in","r",stdin);
	freopen("test.out","w",stdout);
	init(1e6);
	LL T;
	cin>>T;
	while(T--)
	{
		LL n,m;
		scanf("%lld %lld",&n,&m);
		if(n>m) swap(n,m);
		LL ans=1;
		LL l=1,r;
		for(;l<=n;l=r+1)
		{
			r=(min(n/(n/l),m/(m/l)));
			LL val=F[r]*Pow(F[l-1],mod-2)%mod;
			ans=1ll*ans*Pow(Pow(val,(n/l)),(m/l))%mod; 
		}
		printf("%lld\n",ans); 
	}
	return 0;
} 

[HDU4746]Mophues

seek
Let \ (w(n) \) represent the number of prime factors of \ (n \)

\[\sum_{i=1}^n\sum_{j=1}^m[w(gcd(i,j))\leq p] \]

\[\sum_{i=1}^n\sum_{j=1}^m\sum_{d|i,d|j,w(d)\leq p}[gcd(i,j)==d] \]

\[\sum_{d=1,w(d)\leq p}^n\sum_{i=1}^{\lfloor \frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor \frac{m}{d}\rfloor}[gcd(i,j)==1] \]

\[\sum_{d=1,w(d)\leq p}^n\sum_{k=1}\mu(k)\sum_{i=1}^{\lfloor \frac{n}{dk}\rfloor}\sum_{j=1}^{\lfloor \frac{m}{dk}\rfloor}1 \]

\[\sum_{d=1,w(d)\leq p}^n\sum_{k=1}\mu(k) \lfloor \frac{n}{dk}\rfloor \lfloor \frac{m}{dk}\rfloor \]

\[\sum_{T=1}^n\lfloor \frac{n}{T}\rfloor \lfloor \frac{m}{T}\rfloor\sum_{d|T}^n[w(d)\leq p]\mu(\frac{T}{d}) \]

Set \ (S(i,j)=\sum_{d|i}[w(d)==j]\mu(\frac{i}{d})\)
This can be preprocessed by harmonic series \ (O(n\log n) \)
that

\[\sum_{d|T}^n[w(d)\leq p]\mu(\frac{T}{d})=\sum_{j=0}^pS(T,j) \]

Just prefix and sum this

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL N = 5e5+7;
LL S[N][22];
LL v[N],prime[N],tot=0;
LL mu[N];
LL num[N];
void init(LL n)
{
	mu[1]=1;
	for(LL i=2;i<=n;i++)
	{
		if(!v[i])
		{
			v[i]=i;
			prime[++tot]=i;
			num[i]=1;
			mu[i]=-1;
		}
		for(LL j=1;j<=tot;j++)
		{
			if(prime[j]>v[i]||i*prime[j]>n) break;
			v[i*prime[j]]=prime[j];
			if(i%prime[j]==0)
			{
				num[i*prime[j]]=num[i]+1;
				mu[i*prime[j]]=0;
				break;
			}
			else
			{
				num[i*prime[j]]=num[i]+1;
				mu[i*prime[j]]=mu[i]*mu[prime[j]];
			}
		}
	}
	for(LL d=1;d<=n;d++)
	{
		for(LL T=d;T<=n;T+=d)
		S[T][num[d]]=S[T][num[d]]+mu[T/d];
	}
	for(LL p=1;p<=20;p++)
	for(LL i=1;i<=n;i++)
	S[i][p]=S[i][p-1]+S[i][p];
	for(LL p=0;p<=20;p++)
	for(LL i=1;i<=n;i++)
	S[i][p]=S[i-1][p]+S[i][p]; 
}
int main()
{
	freopen("mophues.in","r",stdin);
	freopen("mophues.out","w",stdout);
	init(5e5);
	LL T;
	cin>>T;
	while(T--)
	{
		LL n,m,p;
		scanf("%lld %lld %lld",&n,&m,&p);
		if(p>20)
		{
			printf("%lld\n",1ll*n*m);
			continue;
		}
		if(n>m) swap(n,m);
		LL ans=0;
		LL l=1,r;
		for(;l<=n;l=r+1)
		{
			r=min(n/(n/l),m/(m/l));
			ans=ans+1ll*(n/l)*(m/l)*(S[r][p]-S[l-1][p]);
		}
		printf("%lld\n",ans);
	}
	return 0;
}