P3327 [SDOI2015]约数个数和(莫反&整除分块)
Posted Harris-H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P3327 [SDOI2015]约数个数和(莫反&整除分块)相关的知识,希望对你有一定的参考价值。
P3327 [SDOI2015]约数个数和(莫反&整除分块)
d ( i j ) = ∑ x ∣ i ∑ y ∣ j [ g c d ( x , y ) = 1 ] d(ij)=\\sum\\limits_{x|i}\\sum\\limits_{y|j}[gcd(x,y)=1] d(ij)=x∣i∑y∣j∑[gcd(x,y)=1]
该式子证明部分如下:
然后就是简单套路了。
∑ n ∑ m ∑ x ∣ i ∑ y ∣ j ∑ d ∣ x , d ∣ y μ ( d ) \\large \\sum\\limits^n\\sum\\limits^m\\sum\\limits_{x|i}\\sum\\limits_{y|j}\\sum\\limits_{d|x,d|y}\\mu(d) ∑n∑mx∣i∑y∣j∑d∣x,d∣y∑μ(d)
∑ d = 1 m i n ( n , m ) μ ( d ) ∑ i n ∑ j m ∑ x ∣ i ∑ y ∣ j [ d ∣ g c d ( x , y ) ] \\large \\sum\\limits_{d=1}^{min(n,m)} \\mu(d)\\sum\\limits_i^n\\sum\\limits_j^m\\sum\\limits_{x|i}\\sum\\limits_{y|j}[d|gcd(x,y)] d=1∑min(n,m)μ(d)i∑nj∑mx∣i∑y∣j∑[d∣gcd(x,y)]
= ∑ d = 1 m i n ( n , m ) μ ( d ) ∑ x = 1 n ∑ j = 1 m ⌊ n x ⌋ ⌊ m y ⌋ [ d ∣ g c d ( x , y ) ] =\\large \\sum\\limits_{d=1}^{min(n,m)} \\mu(d)\\sum\\limits_{x=1}^n\\sum\\limits_{j=1}^m\\lfloor\\dfrac{n}{x}\\rfloor\\lfloor\\dfrac{m}{y}\\rfloor [d|gcd(x,y)] =d=1∑min(n,m)μ(d)x=1∑nj=1∑m⌊xn⌋⌊ym⌋[d∣gcd(x,y)]
= ∑ d = 1 m i n ( n , m ) μ ( d ) ∑ x = 1 n d ∑ j = 1 m d ⌊ n x d ⌋ ⌊ m y d ⌋ =\\large \\sum\\limits_{d=1}^{min(n,m)} \\mu(d)\\sum\\limits_{x=1}^{\\dfrac{n}{d}}\\sum\\limits_{j=1}^{\\dfrac{m}{d}}\\lfloor\\dfrac{n}{xd}\\rfloor\\lfloor\\dfrac{m}{yd}\\rfloor =d=1∑min(n,m)μ(d)x=1∑dnj=1∑dm⌊xdn⌋⌊ydm⌋
∑ d = 1 m i n ( n , m ) μ ( d ) ( ∑ x = 1 n d ⌊ n x d ⌋ ) 2 \\large \\sum\\limits_{d=1}^{min(n,m)} \\mu(d)(\\sum\\limits_{x=1}^{\\dfrac{n}{d}} \\lfloor\\dfrac{n}{xd}\\rfloor)^2 d=1∑min(n,m)μ(d)(x=1∑dn⌊xdn⌋)2
后面就是整除分块,预处理一下前缀和,左边就是 μ \\mu μ 线筛预处理前缀和即可。
然后再整除分块一下就欧克了。
code
// Problem: P3327 [SDOI2015]约数个数和
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3327
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// Date: 2021-07-07 19:25:15
// --------by Herio--------
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=5e4+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define ios ios::sync_with_stdio(false),cin.tie(0)
void Print(int *a,int n){
for(int i=1;i<n;i++)
printf("%d ",a[i]);
printf("%d\\n",a[n]);
}
int mu[N],p[N],cnt;
ll pre[N];
bitset<N>vis;
void init(int n){
vis[1]=mu[1]=1;
for(int i=2;i<=n;i++){
if(!vis[i]) p[++cnt]=i,mu[i]=-1;
for(int j=1;j<=cnt&&i*p[j]<=n;j++){
vis[i*p[j]]=1;
if(i%p[j]==0){
break;
}
mu[i*p[j]]=mu[i]*mu[p[j]];
}
}
for(int i=1;i<=n;i++){
mu[i]+=mu[i-1];
ll s=0;
for(int l=1,r;l<=i;l=r+1){
r=(i/(i/l));
s+=1LL*(r-l+1)*(i/l);
}
pre[i]=s;
}
}
ll fun(int n,int m){
ll s=0;
for(int l=1,r;l<=min(n,m);l=r+1){
r=min(n/(n/l),m/(m/l));
s+=1LL*pre[n/l]*pre[m/l]*(mu[r]-mu[l-1]);
}
return s;
}
int main(){
int t;scanf("%d",&t);
init(N-1);
while(t--){
int n,m;
scanf("%d%d",&n,&m);
printf("%lld\\n",fun(n,m));
}
return 0;
}
以上是关于P3327 [SDOI2015]约数个数和(莫反&整除分块)的主要内容,如果未能解决你的问题,请参考以下文章
洛谷P3327 [SDOI2015]约数个数和 莫比乌斯反演