bzoj2693--莫比乌斯反演+积性函数线性筛

时间:2021-12-02 16:50:08

推导:

bzoj2693--莫比乌斯反演+积性函数线性筛

bzoj2693--莫比乌斯反演+积性函数线性筛

设d=gcd(i,j)

bzoj2693--莫比乌斯反演+积性函数线性筛

利用莫比乌斯函数的性质

bzoj2693--莫比乌斯反演+积性函数线性筛

bzoj2693--莫比乌斯反演+积性函数线性筛

令sum(x,y)=(x*(x+1)/2)*(y*(y+1)/2)

bzoj2693--莫比乌斯反演+积性函数线性筛

令T=d*t

bzoj2693--莫比乌斯反演+积性函数线性筛

设f(T)=bzoj2693--莫比乌斯反演+积性函数线性筛

bzoj2693--莫比乌斯反演+积性函数线性筛

T可以分块。又由于μ是积性函数,积性函数的约束和仍是积性函数,所以f也是积性函数,可以O(n)线性筛求得。总时间复杂度为bzoj2693--莫比乌斯反演+积性函数线性筛

具体筛法看代码。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define mod 100000009
#define _min(a,b) a>b?b:a
#define ll long long
inline char nc(){
static char buf[],*p1=buf,*p2=buf;
if(p1==p2){
p2=(p1=buf)+fread(buf,,,stdin);
if(p1==p2)return EOF;
}
return *p1++;
}
inline void read(int& x){
char c=nc();
for(;c<''||c>'';c=nc());
for(x=;c>=''&&c<='';x=x*+c-,c=nc());
}
int len;
char s[];
inline void print(ll x){
if(!x){
putchar('');putchar('\n');
return;
}
for(len=;x;x/=)s[++len]=x%;
for(;len;len--)putchar(s[len]+);
putchar('\n');
}
inline int sum(ll x,ll y){
return (x*(x+)/%mod)*(y*(y+)/%mod)%mod;
}
int T,i,j,k,n,m,ma,num,p[],x,a[],b[],ans;
ll f[];
bool v[];
int main()
{
read(T);
for(i=;i<=T;i++){
read(a[i]);read(b[i]);
if(a[i]>b[i]){k=a[i];a[i]=b[i];b[i]=k;}
if(a[i]>ma)ma=a[i];
}
f[]=;
for(i=;i<=ma;i++){
if(!v[i]){
p[++num]=i;
f[i]=-(1LL*i*(i-)%mod);
}
for(j=;j<=num&&p[j]*i<=ma;j++){
v[p[j]*i]=;
if(i%p[j])f[i*p[j]]=f[i]*f[p[j]]%mod;else{
f[i*p[j]]=f[i]*p[j]%mod;
break;
}
}
}
for(i=;i<=ma;i++)f[i]=(f[i]+f[i-])%mod;
for(k=;k<=T;k++){
ans=;
for(i=;i<=a[k];i=j+){
j=_min(a[k]/(a[k]/i),b[k]/(b[k]/i));
ans=(ans+(f[j]-f[i-])*sum(a[k]/i,b[k]/i)%mod)%mod;
}
print((ans+mod)%mod);
}
return ;
}

bzoj2693