bzoj2693 jzptab(反演LCM之和)

Description

这里写图片描述

Input

一个正整数T表示数据组数
接下来T行 每行两个正整数 表示N、M

Output

T行 每行一个整数 表示第i组数据的结果

Sample Input

1
4 5

Sample Output

122

HINT

T <= 10000
N, M<=10000000

分析:
关于式子的反演:LCM之和
(我实在不想再来一遍,不过听说舒老师有一种好方法,只能等ta传授了)

所以我们就有了这个式子:

这里写图片描述

但是我们这样就需要枚举两个量,即使是分块,时间复杂度还是无法承受
所以我们利用bzoj2820的奇技淫巧:

令 T=k*d
这里写图片描述

这样就改变了枚举顺序
如果我们能预处理出这里写图片描述
我们就可以在sqrt(n)的时间内求出答案了

这里写图片描述

积性函数的乘积也是积性函数,可以线性筛
  • n是质数:
    这里写图片描述
  • n不是质数:
    • n的非平方质因子i
      这里写图片描述
    • n的其他质因子i(即n=i*p且i|p):这样就会有一部分的mu值等于0,化简完得到:
      这里写图片描述

tip

注意强制类型转换

//这里写代码片
#include<cstdio>
#include<cstring>
#include<iostream>
#define ll long long

using namespace std;

const int N=1e7+2;
const ll p=100000009;
int n,m;
ll sum[N];
int sshu[N>>2],tot=0;
bool no[N];

void make()
{
    sum[1]=1;
    for (int i=2;i<N;i++)
    {
        if (!no[i])
        {
            sshu[++tot]=i;
            sum[i]=(ll)((i-(ll)i*i%p)%p+p)%p;                //ll
        }
        for (int j=1;j<=tot&&sshu[j]*i<N;j++)
        {
            no[sshu[j]*i]=1;
            if (i%sshu[j]==0)
            {
                sum[i*sshu[j]]=(ll)(sum[i]%p*sshu[j]%p)%p;   //ll
                break;
            }
            sum[i*sshu[j]]=(ll)(sum[i]%p*sum[sshu[j]]%p)%p;  //ll
        }
    }

    for (int i=2;i<N;i++) sum[i]=(sum[i]%p+sum[i-1]%p)%p;
}

ll Sum(int n,int m)
{
    return (ll)(n*(n+1)/2%p*m*(m+1)/2%p)%p;
}

int main()
{
    int T;
    make();
    scanf("%d",&T);
    while (T--)
    {
        scanf("%d%d",&n,&m);
        int last;
        ll ans=0;
        for (int i=1;i<=min(n,m);i=last+1)
        {
            last=min(n/(n/i),m/(m/i));
            ans=(ans%p+(Sum(n/i,m/i)%p*(sum[last]-sum[i-1])%p+p)%p)%p;
        }
        printf("%lld\n",ans);
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值