【bzoj2694】Lcm 莫比乌斯反演

Description

这里写图片描述

对于任意的>1的n gcd(a, b)不是n^2的倍数
也就是说gcd(a, b)没有一个因子的次数>=2

Input

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

Output

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

Sample Input

4

2 4

3 3

6 5

8 3

Sample Output

24

28

233

178

HINT

HINT

T <= 10000

N, M<=4000000

Source


和这个差不多->【bzoj2154/2693】Crash的数字表格/jzptab 莫比乌斯反演

就是f的定义不同:

f(n)={1n0nsfnotherwise

然后关于如何筛 Fidid ,就变得很恶心了…

不过还是设 g=Fidid ,推一下 g(pk) ,就很简单了…不过要稍微分类讨论一下…

打代码的时候要和推得式子统一!我草稿纸上写的g然后代码写的F,因此WA了好几次…

因为模的数是2的整数幂,相当于 ans and 2301 ,爆int也无所谓。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;

typedef long long LL;

const int SZ = 5000010;
const int mod = (1 << 30) - 1;

int pri[SZ];
bool vis[SZ];

int g[SZ];
int sum[SZ];

void shai(int n)
{
    g[1] = 1;
    for(int i = 2,tot = 0;i <= n;i ++)
    {
        if(!vis[i]) pri[++ tot] = i,g[i] =  i - i * i;
        for(int j = 1,m;j <= tot && (m = i * pri[j]) <= n;j ++)
        {
            vis[m] = 1;
            if(i % pri[j] == 0)
            {
                int x = i / pri[j];
                if(x % pri[j] == 0) g[m] = 0;
                else g[m] =  -pri[j] * pri[j] * pri[j] * g[x];
                break;
            }
            else
            {
                g[m] = g[i] * g[pri[j]];
            }
        }
    }
    for(int i = 1;i <= n;i ++) 
        sum[i] = sum[i - 1] + g[i];
}


int SUM(int n,int m)
{
    int a = n * (n + 1) >> 1;
    int b = m * (m + 1) >> 1;
    return a * b;
}


int ask(int n,int m)
{
    int ans = 0;
    if(n > m) swap(n,m);
    for(int i = 1,r;i <= n;i = r + 1)
    {
        r = min(n / (n / i),m / (m / i));
        ans += (sum[r] - sum[i - 1]) * SUM(n / i,m / i);
    }
    return ans;
}


int main()
{
    int T;
    scanf("%d",&T);
    shai(4000010);
    while(T --)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        printf("%d\n",ask(n,m) & mod);
    }
    return 0;
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值