SPOJ PGCD - Primes in GCD Table (好题! 莫比乌斯反演+分块求和优化)

PGCD - Primes in GCD Table

Johnny has created a table which encodes the results of some operation -- a function of two arguments. But instead of a boring multiplication table of the sort you learn by heart at prep-school, he has created a GCD (greatest
common divisor) table! So he now has a table (of height a and width
b
), indexed from (1,1) to (a,b), and with the value of field (i,j) equal to gcd(i,j). He wants to know how many times he has used prime numbers when writing the table.

Input

First, t ≤ 10, the number of test cases. Each test case consists of two integers, 1 ≤a,b < 107.

Output

For each test case write one number - the number of prime numbers Johnny wrote in that test case.

Example

Input:
2
10 10
100 100

Output:

30
2791

Added by: Yash
Date: 2009-06-12
Time limit: 0.687s
Source limit: 11111B
Memory limit: 1536MB
Cluster: Cube (Intel Pentium G860 3GHz)
Languages: All except: ERL JS NODEJS PERL 6 VB.net
Resource: Codechef

题目链接:http://www.spoj.com/problems/PGCD/

题目大意:1 <= x <= n,1 <= y <= m,求gcd(x, y)为素数的对数

题目分析:和前一题比只是多了一个上界,难度立马变大

学习了这篇博客才解决了这题http://www.cnblogs.com/iwtwiioi/p/4132095.html

为满足的对数

为满足的对数

那么,很显然,反演后得到

因为题目要求是为质数,那么我们枚举每一个质数,然后得到

∑p是质数n∑1<=d<=n/pμ(d)×?n/pd?×?m/pd?

设T=pd,那么问题可以转换为:

∑p是质数n∑1<=d<=n/pμ(d)×?nT?×?mT?

将问题转换为枚举T得:

∑T=1n∑p≤n且p|T且p是质数μ(Tp)×?nT?×?mT?

化简得

∑T=1n?nT?×?mT?∑p≤n且p|T且p是质数μ(Tp)

g[x]=∑p≤n且p|x且p是质数μ(xp)

那么原式变成

∑T=1n?nT?×?mT?×g[T]

那么我们只需要考虑如何计算g[x]即可!而且如果p不是质数或者p?T,那么g[x]=0

我们发现g[x]似乎可以在线性筛的时候预处理出?x=k×p,p为质数的情况,可得:

g[kp]={μ(k)μ(k)?g[k]当p|k时当p?k时

首先根据定义,此时

g[kp]=∑p′≤n且p′|kp且p′是质数μ(kpp′)

首先考虑p|k时,有kp质因子p的指数>=2

1、当p′=p,那么约掉后还剩下μ(k)

2、当p′≠p,那么p的质数>=2,根据莫比乌斯函数的定义,为0

因此式1+式2=μ(k)

考虑p?k时,有kp质因子p的指数=1

1、当p′=p,那么约掉后同样是μ(k)

2、当p′≠p,那么因为μ是积性函数,且p与kp′互质,那么得到μ(p)μ(kp′),然后提出和式。因为μ(p)=?1,而和式内的和恰好就是g[k]的定义,因此这种情况的个数为?g[k]

因此式1+式2=μ(k)?g[k]

最后分块求和然后乘起来

#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
using namespace std;
int const MAX = 1e7 + 5;
int mob[MAX], p[MAX], g[MAX], sum[MAX];
bool prime[MAX];

int Mobius()
{
    mob[1] = 1;
    int pnum = 0;
    for(int i = 2; i < MAX; i++)
    {
        if(!prime[i])
        {
            p[pnum ++] = i;
            mob[i] = -1;
            g[i] = 1;
        }
        for(int j = 0; j < pnum && i * p[j] < MAX; j++)
        {
            prime[i * p[j]] = true;
            if(i % p[j] == 0)
            {
                mob[i * p[j]] = 0;
                g[i * p[j]] = mob[i];
                break;
            }
            mob[i * p[j]] = -mob[i];
            g[i * p[j]] = mob[i] - g[i];
        }
        sum[i] = sum[i - 1] + g[i];
    }
}

ll cal(int l, int r)
{
    ll ans = 0;
    if(l > r)
        swap(l, r);
    for(int i = 1, last = 0; i <= l; i = last + 1)
    {
        last = min(l / (l / i), r / (r / i));
        ans += (ll) (l / i) * (r / i) * (sum[last] - sum[i - 1]);
    }
    return ans;
}

int main()
{
    Mobius();
    int T;
    scanf("%d", &T);
    while(T--)
    {
        int l, r;
        scanf("%d %d", &l, &r);
        printf("%lld\n", cal(l, r));
    }
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2025-01-03 14:58:16

SPOJ PGCD - Primes in GCD Table (好题! 莫比乌斯反演+分块求和优化)的相关文章

* SPOJ PGCD Primes in GCD Table (需要自己推线性筛函数,好题)

题目大意: 给定n,m,求有多少组(a,b) 0<a<=n , 0<b<=m , 使得gcd(a,b)= p , p是一个素数 这里本来利用枚举一个个素数,然后利用莫比乌斯反演可以很方便得到答案,但是数据量过大,完全水不过去 题目分析过程(从别人地方抄来的) ans = sigma(p, sigma(d, μ(d) * (n/pd) * (m/pd))) Let s = pd, then ans = sigma(s, sigma(p, μ(s/p) * (n/s) * (m/s))

SPOJ - PGCD Primes in GCD Table(莫比乌斯反演)

http://www.spoj.com/problems/PGCD/en/ 题意: 给出a,b区间,求该区间内满足gcd(x,y)=质数的个数. 思路: 设f(n)为 gcd(x,y)=p的个数,那么F(n)为 p | gcd(x,y)的个数,显然可得F(n)=(x/p)*(y/p). 这道题目因为可以是不同的质数,所以需要枚举质数, 但是这样枚举太耗时,所以在这里令t=pk, 这样一来的话,我们只需要预处理u(t/p)的前缀和,之后像之前的题一样分块处理就可以了. 1 #include<ios

SPOJ4491. Primes in GCD Table(gcd(a,b)=d素数,(1&amp;lt;=a&amp;lt;=n,1&amp;lt;=b&amp;lt;=m))加强版

SPOJ4491. Primes in GCD Table Problem code: PGCD Johnny has created a table which encodes the results of some operation -- a function of two arguments. But instead of a boring multiplication table of the sort you learn by heart at prep-school, he has

【UVa11426】GCD - Extreme (II)(莫比乌斯反演)

[UVa11426]GCD - Extreme (II)(莫比乌斯反演) 题面 Vjudge 题解 这.. 直接套路的莫比乌斯反演 我连式子都不想写了 默认推到这里把.. 然后把\(ans\)写一下 \[ans=\sum_{d=1}^nd\sum_{i=1}^{n/d}\mu(i)[\frac{n}{id}]^2\] 令\(T=id\) 然后把\(T\)提出来 \[ans=\sum_{T=1}^n[\frac{n}{T}]^2\sum_{d|T}d\mu(\frac{T}{d})\] 后面那一堆

SPOJ-PGCD Primes in GCD Table

题目链接:https://vjudge.net/problem/SPOJ-PGCD 题目大意: 给定 \(N\) 和 \(M\),求满足 \((1 \le x \le N), (1 \le y \le M)\),且 \(gcd(x,y)\) 为素数的 \((x,y)\) 的对数. 知识点: 莫比乌斯反演 解题思路: 设 \(g(p)\) 表示满足 \((1 \le x \le N), (1 \le y \le M)\),且 \(gcd(x,y) = p\) 的 \((x,y)\) 的对数.直接求

HDU 1695 GCD(容斥 or 莫比乌斯反演)

这题可以用容斥做,然而效率并不高.. 于是学了下莫比乌斯反演(资料百度找) 求出mo数组后 设f(x)为gcd为x的种数 F(x)为gcd为x倍数的种数 那么显然F(x) = (b / x) * (d / x) 莫比乌斯反演之后,得到f(x) = sum(mo[i] * F(i)). 然后还要容斥减去对称重复的.对称重复的情况为min(b, d)小的中,求一遍除2,(因为存在x = y的情况只有(1,1)一种) 最后还要注意特判下k == 0的情况 代码: #include <cstdio>

HDU 4675 GCD of Sequence(莫比乌斯反演 + 打表注意事项)题解

题意: 给出\(M\)和\(a数组\),询问每一个\(d\in[1,M]\),有多少组数组满足:正好修改\(k\)个\(a\)数组里的数使得和原来不同,并且要\(\leq M\),并且\(gcd(a_1,a_2,\dots,a_n)=d\). 思路: 对于每一个\(d\),即求\(f(d)\):修改\(k\)个后\(gcd(a_1,a_2,\dots,a_n)=d\)的对数. 那么假设\(F(d)\):修改\(k\)个后\(gcd(a_1,a_2,\dots,a_n)\)是\(d\)倍数的对数.

SPOJ PGCD(莫比乌斯反演)

传送门:Primes in GCD Table 题意:给定两个数和,其中,,求为质数的有多少对?其中和的范围是. 分析:这题不能枚举质数来进行莫比乌斯反演,得预处理出∑υ(n/p)(n%p==0). #pragma comment(linker,"/STACK:1024000000,1024000000") #include <cstdio> #include <cstring> #include <string> #include <cmat

(转载)关于gcd的8题

发现其实有关gcd的题目还是挺多的,这里根据做题顺序写出8题. [bzoj2818: Gcd] gcd(x,y)=质数, 1<=x,y<=n的对数 做这题的时候,懂得了一个非常重要的转化:求(x, y) = k, 1 <= x, y <= n的对数等于求(x, y) = 1, 1 <= x, y <= n/k的对数!所以,枚举每个质数p(线性筛素数的方法见:线性时间内筛素数和欧拉函数),然后求(x, y) = 1, 1 <= x, y <= n/p的个数.