JZOJ6912. 【2020.12.01提高组模拟】数论(math)

Description

在这里插入图片描述
n , m ≤ 1 e 7 n,m\le1e7 n,m1e7

Solution

  • 后面那个互质数之和由于对称性可以得到是 ϕ ( n ) n / 2 \phi(n)n/2 ϕ(n)n/2,需要特判 n = 1 n=1 n=1
  • 然后把 ϕ ( i j ) \phi(ij) ϕ(ij)拆成 ϕ ( i ) ϕ ( j ) ( i , j ) ϕ ( ( i , j ) ) \phi(i)\phi(j)\frac{(i,j)}{\phi((i,j))} ϕ(i)ϕ(j)ϕ((i,j))(i,j),相当于是一个容斥掉 1 p − 1 \frac{1}{p-1} p11
  • 然后直接枚举 ( i , j ) (i,j) (i,j),由于 n , m ≤ 1 e 7 n,m\le1e7 n,m1e7,可以直接高维前缀和、差分求gcd,枚举gcd,求出贡献即可(才不要什么莫比乌斯反演呢,莫比乌斯反演一般做 1 e 9 1e9 1e9级别的整除分块)。
  • 高维前缀和时间复杂度与埃氏筛一样。

有关phi的性质

1. ϕ = μ ∗ i d \phi=\mu*id ϕ=μid,证明: ϕ ( n ) = ∑ i = 1 n [ ( i , n ) = 1 ] = ∑ d ∣ n μ ( d ) n d \phi(n)=\sum_{i=1}^n[(i,n)=1]=\sum_{d|n}\mu(d)\frac{n}{d} ϕ(n)=i=1n[(i,n)=1]=dnμ(d)dn
2. ∑ i = 1 n ∑ j = 1 m ( i , j ) = ∑ d = 1 n d ∑ k = 1 n / d μ ( k ) ( n / k d ) ( m / k d ) = ∑ T = 1 n ϕ ( T ) ( n / T ) ( m / T ) \sum_{i=1}^n\sum_{j=1}^m(i,j)=\sum_{d=1}^nd\sum_{k=1}^{n/d}\mu(k)(n/kd)(m/kd)=\sum_{T=1}^n\phi(T)(n/T)(m/T) i=1nj=1m(i,j)=d=1ndk=1n/dμ(k)(n/kd)(m/kd)=T=1nϕ(T)(n/T)(m/T)
3. ∑ i [ ( n , i ) = 1 ] i = ( ϕ ( n ) n + [ i 2 = n ] ) / 2 \sum_{i}[(n,i)=1]i=(\phi(n)n+[i^2=n])/2 i[(n,i)=1]i=(ϕ(n)n+[i2=n])/2

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define maxn 10000005
#define ll long long 
#define mo 998244353
using namespace std;

int n,m,i,j,k,lim;
int tot,pri[maxn],bz[maxn],phi[maxn];
int f[maxn],g[maxn];
ll ans;

ll ksm(ll x,ll y){
	ll s=1;
	for(;y;y/=2,x=x*x%mo) if (y&1)
		s=s*x%mo;
	return s;
}

void getpri(){
	phi[1]=1;
	for(i=2;i<=lim;i++) {
		if (!bz[i]) pri[++tot]=i,phi[i]=i-1;
		for(j=1;j<=tot&&i*pri[j]<=lim;j++){
			bz[i*pri[j]]=1;
			if (i%pri[j]==0) {
				phi[i*pri[j]]=phi[i]*pri[j];
				break;
			} else phi[i*pri[j]]=phi[i]*(pri[j]-1);
		}
	}
}

int main(){
	freopen("ceshi.in","r",stdin);
//	freopen("math.in","r",stdin);
//	freopen("math.out","w",stdout);
	scanf("%d%d",&n,&m),lim=max(n,m);
	getpri();
	for(i=1;i<=n;i++) f[i]=(ll)phi[i]*i%mo;
	for(i=1;i<=m;i++) g[i]=(ll)phi[i]*i%mo;
	for(i=1;i<=tot;i++){
		int x=pri[i];
		for(j=n/x*x;j;j-=x) (f[j/x]+=f[j])%=mo;
		for(j=m/x*x;j;j-=x) (g[j/x]+=g[j])%=mo;
	}
	for(i=1;i<=lim;i++) f[i]=1ll*f[i]*g[i]%mo;
	for(i=1;i<=tot;i++){
		int x=pri[i];
		for(j=x;j<=lim;j+=x) (f[j/x]-=f[j])%=mo;
	}
//	for(i=1;i<=lim;i++) f[i]=1ll*f[i]*ksm(phi[i],mo-2)%mo*ksm(i,n+1)%mo;
	for(i=1;i<=tot;i++){
		int p=pri[i]; 
		ll mul=ksm(p,n+1)*ksm(p-1,mo-2)%mo;
		ll inv=ksm(p,mo-2)*ksm(p,n+1)%mo;
		for(j=p;j<=lim;j+=p){
			int x=j/p; ll s=mul;
			while (x%p==0) s=s*inv%mo,x/=p;
			f[j]=(ll)f[j]*s%mo;
		}
	}
	for(i=1;i<=lim;i++) ans+=f[i]; 
	printf("%lld\n",(ans%mo+1+mo)*ksm(2,mo-2)%mo);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值