給定整數N,求1<=x,y<=N且Gcd(x,y)為素數的
數對(x,y)有多少對.
BZOJ 2818 Gcd (莫比烏斯反演 或 尤拉函式)
2818: Gcd
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 2534 Solved: 1129
[Submit][Status][Discuss]
Description
Input
一個整數N
Output
如題
Sample Input
4
Sample Output
4
HINT
hint
對於樣例(2,2),(2,4),(3,3),(4,2)
1<=N<=10^7
Source
題目連結:http://www.lydsy.com/JudgeOnline/problem.php?id=2818
題目分析:兩種姿勢,莫比烏斯反演或者尤拉函式,先說簡單的方法,尤拉函式,因為只有一個上界n,所以變換一下1 <= x / p, y / p <= n / p,GCD(x / p, y / p) == 1,
直接求尤拉函式,令num[i]表示1到i中 1<=x,y<=i 且gcd(x,y) == 1個對數,顯然有num[i] = 1 + phi[j] * 2,(1 < j <= i),這個1指的是(1, 1),乘2是因為(1, 2) (2, 1)算兩個不同的,那麼最後根據我們先前變換的公式,累加num[n / p]的值即可
#include <cstdio>
#include <cstring>
#define ll long long
int const MAX = 1e7 + 5;
int p[MAX], phi[MAX];
bool prime[MAX];
ll num[MAX];
int pnum;
void get_eular(int n)
{
pnum = 0;
memset(prime, true, sizeof(prime));
for(int i = 2; i <= n; i++)
{
if(prime[i])
{
p[pnum ++] = i;
phi[i] = i - 1;
}
for(int j = 0; j < pnum && i * p[j] <= n; j++)
{
prime[i * p[j]] = false;
if(i % p[j] == 0)
{
phi[i * p[j]] = phi[i] * p[j];
break;
}
phi[i * p[j]] = phi[i] * (p[j] - 1);
}
}
}
int main()
{
int n;
ll ans = 0;
scanf("%d", &n);
get_eular(n);
num[1] = 1;
for(int i = 2; i <= n; i++)
num[i] = num[i - 1] + 2 * phi[i];
for(int i = 0; i < pnum; i++)
if(n / p[i] > 0)
ans += num[n / p[i]];
printf("%lld\n", ans);
}
這題也可以用莫比烏斯反演做,還是做上述變換,1 <= x / p, y / p <= n / p,GCD(x / p, y / p) == 1,這種題真的做爛了,懶得說了直接貼
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
using namespace std;
int const MAX = 1e7 + 5;
int mob[MAX], p[MAX], sum[MAX];
bool prime[MAX];
int pnum;
void Mobius(int n)
{
pnum = 0;
memset(prime, true, sizeof(prime));
memset(sum, 0, sizeof(sum));
mob[1] = 1;
sum[1] = 1;
for(int i = 2; i <= n; i++)
{
if(prime[i])
{
p[pnum ++] = i;
mob[i] = -1;
}
for(int j = 0; j < pnum && i * p[j] <= n; j++)
{
prime[i * p[j]] = false;
if(i % p[j] == 0)
{
mob[i * p[j]] = 0;
break;
}
mob[i * p[j]] = -mob[i];
}
sum[i] = sum[i - 1] + mob[i];
}
}
ll cal(int n)
{
ll res = 0;
for(int i = 1, last = 0; i <= n; i = last + 1)
{
last = n / (n / i);
res += (ll) (n / i) * (n / i) * (sum[last] - sum[i - 1]);
}
return res;
}
int main()
{
int n;
ll ans = 0;
scanf("%d", &n);
Mobius(n);
for(int i = 0; i < pnum; i++)
if(n / p[i] > 0)
ans += cal(n / p[i]);
printf("%lld\n", ans);
}
相關文章
- bzoj2818: Gcd(尤拉函式)GC函式
- FZU 1969 && UVA 11426 GCD Extreme (尤拉函式 或 莫比烏斯反演)GCREM函式
- [bzoj2818]gcdGC
- Hackerrank GCD Product(莫比烏斯反演)GC
- HDU2588GCD(尤拉函式)GC函式
- ZOJ 3868 GCD Expectation (容斥+莫比烏斯反演)GC
- HDU 1695 GCD (容斥 + 莫比烏斯反演)GC
- 洛谷 P2257 YY的GCD(莫比烏斯反演)GC
- HDU 1695-GCD(容斥原理+尤拉函式)GC函式
- 莫比烏斯反演
- SPOJ PGCD - Primes in GCD Table (好題! 莫比烏斯反演+分塊求和優化)GC優化
- 尤拉函式φ函式
- BZOJ 3309 DZY Loves Math (莫比烏斯反演的應用 好題)
- BZOJ2839/LG10596 集合計數 題解(二項式反演+擴充套件尤拉定理)套件
- 4939 尤拉函式函式
- 莫比烏斯函式函式
- 莫比烏斯反演學習筆記筆記
- 比較典的莫比烏斯反演
- bzoj2190: [SDOI2008]儀仗隊(尤拉函式)函式
- 尤拉函式入門函式
- 尤拉函式詳解函式
- poj 2478 尤拉函式函式
- 淺談尤拉函式函式
- 尤拉函式的應用函式
- BZOJ3853 : GCD ArrayGC
- 狄利克雷卷積 & 莫比烏斯反演卷積
- HDU 4746 Mophues (莫比烏斯反演應用)
- POJ 3904 Sky Code (容斥+莫比烏斯反演)
- GCD、dispatch 函式介紹GC函式
- 狄利克雷卷積與莫比烏斯反演卷積
- 尤拉函式性質和模版函式
- 轉載:尤拉函式知識點總結及程式碼模板及尤拉函式表函式
- iOS-GCD常用函式和柵欄函式iOSGC函式
- 數論線性篩總結 (素數篩,尤拉函式篩,莫比烏斯函式篩,前n個數的約數個數篩)函式
- 演算法隨筆——數論之莫比烏斯反演演算法
- Note -「因數的尤拉函式求和」函式
- POJ 2478-Farey Sequence(尤拉函式)函式
- B.日記和尤拉函式函式