LCM(i,j)求和 (莫比乌斯函数)(NKOJ3958/BZOJ2693)

题意:

ni=1mj=1lcm(i,j) ∑ i = 1 n ∑ j = 1 m l c m ( i , j )
n,m=1e7,多组输入


O(N) O ( N ) 版本:

遇到lcm首先是换成gcd, Ans=ni=1mj=1ijgcd(i,j) A n s = ∑ i = 1 n ∑ j = 1 m i ∗ j g c d ( i , j ) ,再换成因子角度,设: gcd(i,j)=d,min(n,m)=N g c d ( i , j ) = d , m i n ( n , m ) = N ,有:

d=1Ni=1nj=1m[gcd(i,j)==d]ijd ∑ d = 1 N ∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) == d ] i ∗ j d
gcd==d g c d == d 按照套路可以进行莫比乌斯的倍数反演:
g(d)=i=1nj=1m[gcd(i,j)==d]ijd=1N/df(d)=d|DNg(D)=i=1nj=1m[d|gcd(i,j)]ijf(d)=d2(1+[nd])([nd])2(1+[md])([md])2g(d)=d|DNu(Dd)f(D)g(1)=i=1Nu(i)f(i)Ans=d=1N1dd|DNu(Dd)f(D)i=D/dAns=d=1N1di=1[Nd]u(i)f(id)fAns=d=1Ndi=1[Nd]u(i)i2(1+[nid])([nid])2(1+[mid])([mid])2 g ( d ) = ∑ i = 1 n ∑ j = 1 m [ g c d ( i , j ) == d ] i ∗ j ( 去 掉 ∑ d = 1 N 和 / d 才 是 积 性 函 数 , 才 容 易 反 演 ) 构 造 : f ( d ) = ∑ d | D N g ( D ) = ∑ i = 1 n ∑ j = 1 m [ d | g c d ( i , j ) ] i ∗ j 显 然 : f ( d ) = d 2 ∗ ( 1 + [ n d ] ) ( [ n d ] ) 2 ∗ ( 1 + [ m d ] ) ( [ m d ] ) 2 反 演 : g ( d ) = ∑ d | D N u ( D d ) f ( D ) 那 么 : g ( 1 ) = ∑ i = 1 N u ( i ) f ( i ) 代 入 : A n s = ∑ d = 1 N 1 d ∑ d | D N u ( D d ) f ( D ) 令 i = D / d 得 : A n s = ∑ d = 1 N 1 d ∑ i = 1 [ N d ] u ( i ) f ( i d ) 最 后 带 入 f 得 : A n s = ∑ d = 1 N d ∑ i = 1 [ N d ] u ( i ) ∗ i 2 ∗ ( 1 + [ n i d ] ) ( [ n i d ] ) 2 ∗ ( 1 + [ m i d ] ) ( [ m i d ] ) 2

观察发现 [Nd] [ N d ] [nid] [ n i d ] 可以整除分块,那么时间复杂度为 O(nn)=O(n) O ( n ∗ n ) = O ( n ) ,一般的题目是可以过了,但是案例数多的就不行了


O(N) O ( N ) 版本:

Ans=d=1Ndi=1[Nd]u(i)i2(1+[nid])([nid])2(1+[mid])([mid])2=d=1Ndi|du(i)i2(1+[nid])([nid])2(1+[mid])([mid])2 A n s = ∑ d = 1 N d ∑ i = 1 [ N d ] u ( i ) ∗ i 2 ∗ ( 1 + [ n i d ] ) ( [ n i d ] ) 2 ∗ ( 1 + [ m i d ] ) ( [ m i d ] ) 2 = ∑ d = 1 N d ∑ i | d u ( i ) ∗ i 2 ∗ ( 1 + [ n i d ] ) ( [ n i d ] ) 2 ∗ ( 1 + [ m i d ] ) ( [ m i d ] ) 2 ( 这 步 在 写 杜 教 筛 ( 上 ) 中 有 证 明 )

改变枚举变量,令 D=id D = i ∗ d 得 :

Ans=D=1ND(1+[nD])([nD])2(1+[mD])([mD])2i|Du(i)i A n s = ∑ D = 1 N D ∗ ( 1 + [ n D ] ) ( [ n D ] ) 2 ∗ ( 1 + [ m D ] ) ( [ m D ] ) 2 ∑ i | D u ( i ) ∗ i

想办法快速求出 i|Du(i)i ∑ i | D u ( i ) ∗ i :

u(i)ii|Du(i)iF(D)=i|Du(i)iF(pq)=1pF(pq11pq22pqkk)=(1p1)...(1pk)DF(D)线[nD]O(N) ∵ u ( i ) ∗ i 为 积 性 ∴ ∑ i | D u ( i ) ∗ i 为 积 性 设 : F ( D ) = ∑ i | D u ( i ) ∗ i 显 然 : F ( p q ) = 1 − p 那 么 : F ( p 1 q 1 ∗ p 2 q 2 ∗ … p k q k ) = ( 1 − p 1 ) ∗ . . . ( 1 − p k ) ∴ D ∗ F ( D ) 可 以 直 接 放 进 线 性 筛 预 , 再 处 理 出 前 缀 和 ∴ 只 需 要 对 [ n D ] 分 块 即 可 , 时 间 复 杂 度 O ( N )

代码:

#include<bits/stdc++.h>
#define LL long long
using namespace std;
int read(){int t;
    scanf("%d",&t);return t;
}

const int N=1e7+5;
const int mod=1e8+9;//注意模数
LL pri[N>>1],now;
bool vis[N];
LL sum[N];
init(){
    now=0;vis[1]=1;
    for(LL i=2;i<N;i++){//预处理D*F(D)
        if(!vis[i])pri[++now]=i,sum[i]=(i*(1-i)%mod+mod)%mod;
        for(LL j=1,mul=2*i;j<=now&&mul<N;j++,mul=pri[j]*i){
            vis[mul]=1;
            if(i%pri[j]==0){sum[mul]=sum[i]*pri[j]%mod;break;}
            sum[mul]=sum[i]*sum[pri[j]]%mod;
        }
    }
    sum[1]=1;
    for(int i=2;i<N;i++)sum[i]=(sum[i]+sum[i-1])%mod;//变成前缀数组
}

LL cal(LL x,LL y){
    return ((1+x)*x/2%mod)*((1+y)*y/2%mod)%mod;
}

int main(){
    init();
    int t=read();
    while(t--){
        LL n=read(),m=read();
        LL NN=min(n,m);
        LL ans=0;
        for(LL l=1,r;l<=NN;l=r+1){
            r=min(n/(n/l),m/(m/l));
            ans=(ans+(sum[r]-sum[l-1]+mod)%mod*cal(n/l,m/l)%mod)%mod;
        }
        printf("%lld\n",ans);
    }
}
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值