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<iostream>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<cstdio>
 5 #include<sstream>
 6 #include<vector>
 7 #include<stack>
 8 #include<queue>
 9 #include<cmath>
10 #include<map>
11 #include<set>
12 using namespace std;
13 typedef long long ll;
14 typedef pair<int,int> pll;
15 const int INF = 0x3f3f3f3f;
16 const int maxn = 1e7 + 100;
17
18 int a, b;
19
20 bool check[maxn];
21 int prime[maxn];
22 int mu[maxn];
23 ll sum[maxn];
24
25 void Mobius()
26 {
27     memset(check, false, sizeof(check));
28     mu[1] = 1;
29     int tot = 0;
30     for (int i = 2; i <= maxn; i++)
31     {
32         if (!check[i])
33         {
34             prime[tot++] = i;
35             mu[i] = -1;
36         }
37         for (int j = 0; j < tot; j++)
38         {
39             if (i * prime[j] > maxn)
40             {
41                 break;
42             }
43             check[i * prime[j]] = true;
44             if (i % prime[j] == 0)
45             {
46                 mu[i * prime[j]] = 0;
47                 break;
48             }
49             else
50             {
51                 mu[i * prime[j]] = -mu[i];
52             }
53         }
54     }
55
56     sum[0]=0;
57     for(int i=0;i<tot;i++)
58     {
59         for(int j=prime[i];j<maxn;j+=prime[i])
60         {
61             sum[j]+=mu[j/prime[i]];
62         }
63     }
64     for(int i=1;i<maxn;i++)
65         sum[i]+=sum[i-1];
66     return ;
67 }
68
69 ll solve(int n, int m)
70 {
71     if(n>m)  swap(n,m);
72     ll ans=0;
73
74     for(int i=1,last=0;i<=n;i=last+1)
75     {
76         last=min(n/(n/i),m/(m/i));
77         ans+=(sum[last]-sum[i-1])*(n/i)*(m/i);
78     }
79     return ans;
80 }
81
82
83 int main()
84 {
85     //freopen("in.txt","r",stdin);
86     int T;
87     Mobius();
88
89     scanf("%d",&T);
90     while(T--)
91     {
92         scanf("%d%d",&a,&b);
93         ll ans = solve(a,b);
94         printf("%lld\n",ans);
95     }
96     return 0;
97 }
时间: 2024-10-10 07:08:58

SPOJ - PGCD Primes in GCD Table(莫比乌斯反演)的相关文章

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 (greate

* 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))

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

【HDU1695】GCD(莫比乌斯反演)

[HDU1695]GCD(莫比乌斯反演) 题面 题目大意 求\(a<=x<=b,c<=y<=d\) 且\(gcd(x,y)=k\)的无序数对的个数 其中,你可以假定\(a=c=1\) 所有数都\(<=100000\) 数据组数\(<=3000\) 题解 莫比乌斯反演 作为一道莫比乌斯反演的题目 首先我们要迈出第一步 如果有\(gcd(x,y)=k\) 那么,我们就有\(gcd(\frac{x}{k},\frac{y}{k})=1\) 所以,现在问题相当于转化为了求 \(

【BZOJ2820】YY的GCD(莫比乌斯反演)

[BZOJ2820]YY的GCD(莫比乌斯反演) 题面 讨厌权限题!!!提供洛谷题面 题解 单次询问\(O(n)\)是做过的一模一样的题目 但是现在很显然不行了, 于是继续推 \[ans=\sum_{d=1}^n[d\_is\_prime]\sum_{i=1}^{n/d}[\frac{n}{id}][\frac{m}{id}]\] 老套路了 令\(T=id\) \[ans=\sum_{T=1}^{n}[\frac{n}{T}][\frac{m}{T}]\sum_{d|T}[d\_is\_prim

hdu_1695: GCD 【莫比乌斯反演】

题目链接 这题求[1,n],[1,m]gcd为k的对数.而且没有顺序. 设F(n)为公约数为n的组数个数 f(n)为最大公约数为n的组数个数 然后在纸上手动验一下F(n)和f(n)的关系,直接套公式就好了.注意要删去重复的. 关于 莫比乌斯反演 的结论 #include<bits/stdc++.h> using namespace std; typedef long long LL; const int maxn=1e6; int prime[maxn+5]; bool check[maxn+

acdream 1148 GCD SUM 莫比乌斯反演 ansx,ansy

GCD SUM Time Limit: 8000/4000MS (Java/Others)Memory Limit: 128000/64000KB (Java/Others) SubmitStatisticNext Problem Problem Description 给出N,M执行如下程序:long long  ans = 0,ansx = 0,ansy = 0;for(int i = 1; i <= N; i ++)   for(int j = 1; j <= M; j ++)     

HDU 1695 GCD (莫比乌斯反演)

传送门 GCD Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 9749    Accepted Submission(s): 3648 Problem Description Given 5 integers: a, b, c, d, k, you're to find x in a-b, y in c-d that GCD(x, y)

HDU 1695 GCD 【莫比乌斯反演例题】

GCDTime Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4291 Accepted Submission(s): 1502   Problem DescriptionGiven 5 integers: a, b, c, d, k, you're to find x in a...b, y in c...d that GCD(x, y) = k.