[BZOJ4407]于神之怒加强版-题解

版权声明:转载注明出处,谢谢,有问题可以向博主联系 https://blog.csdn.net/VictoryCzt/article/details/85081828

题目地址


题意简述

给定 T , K T,K ,表示有 T T 组询问,每组给定 n , m n,m ,求下面式子的值:

i = 1 n j = 1 m g c d ( i , j ) K \sum_{i=1}^n\sum_{j=1}^mgcd(i,j)^K

输出在 m o d    1 0 9 + 7 \mod 10^9+7 意义下的值。
n , m , K 5 × 1 0 6 , T 2000 n,m,K\leq 5\times 10^6,T\leq 2000


其实莫比乌斯反演的题目大多都是套路啦QWQ

根据套路,我们枚举 g c d gcd ,即可将原式转换为(这里默认 n m n\leq m ,如果不满足则交换):

= d = 1 n d K i = 1 n j = 1 m [ g c d ( i , j ) = d ] = d = 1 n d K i = 1 n d j = 1 m d [ g c d ( i , j ) = 1 ] = d = 1 n d K i = 1 n d j = 1 m d w i , w j μ ( w ) = d = 1 n d K w = 1 n d μ ( w ) n d w m d w =\sum_{d=1}^nd^K\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=d]\\ =\sum_{d=1}^nd^K\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{d}\rfloor}[gcd(i,j)=1]\\ =\sum_{d=1}^nd^K\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{d}\rfloor}\sum_{w|i,w|j}\mu(w)\\ =\sum_{d=1}^nd^K\sum_{w=1}^{\lfloor\frac{n}{d}\rfloor}\mu(w)\left\lfloor\frac{n}{dw}\right\rfloor\left\lfloor\frac{m}{dw}\right\rfloor

这些都是莫比乌斯反演的套路啦,接下来,为了每次能够在 O ( n ) O(\sqrt{n}) 的时间内快速回答,我们就枚举 d w dw ,令 T = d w T=dw 则得到:

T = 1 n n T m T d T d K μ ( T d ) \sum_{T=1}^n\left\lfloor\frac{n}{T}\right\rfloor\left\lfloor\frac{m}{T}\right\rfloor\sum_{d|T}d^K\mu(\frac{T}{d})

然后我们线性筛出后面的:
f ( n ) = d n d K μ ( T d ) f(n)=\sum_{d|n}d^K\mu(\frac{T}{d})
即可(这个显然是个积性函数, f = i d k μ f=id^k\bigotimes \mu 两个积性函数的狄利克雷卷积也是积性函数)。

也可以枚举倍数用 O ( n ( l o g n × ) ) O(n(logn\times快速幂)) 的复杂度算,但是在这个题上面就太慢了,5e6可能有点卡。

我们根据欧拉筛三步走来推:

  1. 考虑 f ( p ) f(p) p p 为质数的值的计算:

d p d k μ ( p d ) \sum_{d|p}d^k\mu(\frac{p}{d})
显然, d = 1 , p d=1,p 这两个,所以直接算出为 p k 1 p^k-1

  1. 考虑 f ( p c ) f(p^c) p p 为质数的值的计算:

d p c d k μ ( p c d ) = i = 0 c ( p i ) k μ ( p c p i ) = i = 0 c ( p i ) k μ ( p c i ) \sum_{d|p^c}d^k\mu(\frac{p^c}{d})\\ =\sum_{i=0}^c(p^i)^k\mu(\frac{p^c}{p^i})\\ =\sum_{i=0}^c(p^i)^k\mu(p^{c-i})

由于当指数大于1的时候 μ ( p i ) = 0 \mu(p^i)=0 ,所以只有 i = c , c 1 i=c,c-1 两个有值,直接代入计算即可,答案为 p k c p k c k p^{kc}-p^{kc-k}

  1. 考虑 f ( x ) f(x) x = p c y x=p^cy ,其中 p y p\bot y

那么根据积性函数,直接转化为 f ( x ) = f ( p c ) f ( y ) f(x)=f(p^c)f(y) 即可,其中的 f ( y ) = f ( x p c ) f(y)=f(\frac{x}{p^c})

上面有些小写 k k 就是大写的 K K ,懒得改了QWQ

下面就是代码了:

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll Mod=1e9+7;
const int M=5e6+10,MAX=5e6;
int n,m,K,T;
ll fpow(ll a,ll b){
	ll ans=1;
	for(;b;b>>=1,a=(a*a)%Mod)if(b&1)ans=(ans*a)%Mod;
	return ans;
}
ll F[M],prime[M],P[M],Invp[M],cnt;
ll c[M],f[M],p[M];bool vis[M];
//ll C[M],mu[M];
void init(){
	F[1]=1;
//	mu[1]=1;
	for(int i=2;i<=MAX;i++){
		if(!vis[i]){
			prime[++cnt]=i;P[i]=fpow(i,K);Invp[i]=fpow(P[i],Mod-2);//逆元处理p^{-k}
			F[i]=P[i]-1;c[i]=1;f[i]=i;p[i]=i;
			if(F[i]<0)F[i]+=Mod;
//			mu[i]=Mod-1;
		}
		for(int j=1,v;j<=cnt&&i*prime[j]<=MAX;j++){
			v=i*prime[j];
			vis[v]=1;
			if(!(i%prime[j])){
				c[v]=c[i]+1;f[v]=f[i];p[v]=p[i]*f[i];
				ll vv=fpow(P[f[v]],c[v]);
				F[v]=F[v/p[v]]*(((vv-vv*Invp[f[v]]%Mod)%Mod+Mod)%Mod)%Mod;
				break;
			}
			F[v]=F[i]*F[prime[j]]%Mod;
			c[v]=1;f[v]=prime[j];p[v]=prime[j];
//			mu[v]=(Mod-mu[i]);
		}
	}//nlogn的线性筛预处理 
//	for(int i=1;i<=MAX;i++){
//		ll v=fpow(i,K);
//		for(int j=i;j<=MAX;j+=i){
//			C[j]=(C[j]+v*mu[j/i]%Mod)%Mod;
//		}
//	}//nlog^2n的预处理 
	for(int i=2;i<=MAX;i++)F[i]=(F[i]+F[i-1])%Mod;
}
ll solve(){
	ll ans=0;
	if(n>m)swap(n,m);
	for(int i=1,j;i<=n;i=j+1){
		j=min(n/(n/i),m/(m/i));
		ans=(ans+((F[j]-F[i-1])%Mod+Mod)%Mod*(n/i)%Mod*(m/i)%Mod)%Mod;
	}
	return ans;
}
int main(){
	scanf("%d%d",&T,&K);
	init();
	while(T--){
		scanf("%d%d",&n,&m);
		printf("%lld\n",solve());
	}
	return 0;
}

拓展

其实如果这个题目只有一次询问,且 n , m 1 0 8 , K 50 n,m\leq 10^8,K\leq 50 的话,无法线性筛的时候我们可以用杜教筛。

原式相当于 i d k μ id^k\bigotimes \mu ,我们令 f = i d k μ , g = 1 f=id^k\bigotimes \mu,g=\mathbf{1} ,那么 f g = i d k μ 1 f\bigotimes g=id^k\bigotimes \mu\bigotimes \mathbf1

先把后面两个卷起来可以得到 μ 1 = ϵ \mu\bigotimes \mathbf1=\epsilon ,那么 f g = i d k f\bigotimes g=id^k

套入杜教筛的公式中可以得到:

F ( n ) = i = 1 n i k i = 2 n F ( n i ) F(n)=\sum_{i=1}^ni^k-\sum_{i=2}^nF(\left\lfloor\frac{n}{i}\right\rfloor)

其中 i k i^k 的前缀和可以用拉格朗日差值法在 O ( k l o g k ) O(klogk) 的时间内求出,所以总的复杂度为 O ( n 2 3 k l o g k ) O(n^{\frac{2}{3}}klogk) ,在3s左右能跑出 n 1 0 8 , K 50 n\leq10^8,K\leq 50


End

吐槽:莫比乌斯反演和杜教筛的题目都是好多套路和很多神奇的式子啊QWQ,要多写写题,总结总结

其实很多时候杜教筛不知道用什么 g g 函数去卷要求的 f f 函数,可以根据经验积累,或者使用贝尔级数之类的去推。

如果杜教筛中还有不好求的前缀和,可以再套一层杜教筛,复杂度仍然为 O ( n 2 3 ) O(n^{\frac{2}{3}}) ,只是空间时间常数大了。

猜你喜欢

转载自blog.csdn.net/VictoryCzt/article/details/85081828
今日推荐