HDU 4746 Mophues (莫比烏斯反演應用)
Mophues
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 327670/327670 K (Java/Others)
Total Submission(s): 980 Accepted Submission(s): 376
Problem Description
As we know, any positive integer C ( C >= 2 ) can be written as the multiply of some prime numbers:
C = p1×p2× p3× ... × pk
which p1, p2 ... pk are all prime numbers.For example, if C = 24, then:
24 = 2 × 2 × 2 × 3
here, p1 = p2 = p3 = 2, p4 = 3, k = 4
Given two integers P and C. if k<=P( k is the number of C's prime factors), we call C a lucky number of P.
Now, XXX needs to count the number of pairs (a, b), which 1<=a<=n , 1<=b<=m, and gcd(a,b) is a lucky number of a given P ( "gcd" means "greatest common divisor").
Please note that we define 1 as lucky number of any non-negative integers because 1 has no prime factor.
C = p1×p2× p3× ... × pk
which p1, p2 ... pk are all prime numbers.For example, if C = 24, then:
24 = 2 × 2 × 2 × 3
here, p1 = p2 = p3 = 2, p4 = 3, k = 4
Given two integers P and C. if k<=P( k is the number of C's prime factors), we call C a lucky number of P.
Now, XXX needs to count the number of pairs (a, b), which 1<=a<=n , 1<=b<=m, and gcd(a,b) is a lucky number of a given P ( "gcd" means "greatest common divisor").
Please note that we define 1 as lucky number of any non-negative integers because 1 has no prime factor.
The first line of input is an integer Q meaning that there are Q test cases.
Then Q lines follow, each line is a test case and each test case contains three non-negative numbers: n, m and P (n, m, P <= 5×105. Q <=5000).
Then Q lines follow, each line is a test case and each test case contains three non-negative numbers: n, m and P (n, m, P <= 5×105. Q <=5000).
For each test case, print the number of pairs (a, b), which 1<=a<=n , 1<=b<=m, and gcd(a,b) is a lucky number of P.
2
10 10 0
10 10 1
63
93
題目連結:http://acm.hdu.edu.cn/showproblem.php?pid=4746
題目大意:定義num[i]為將i唯一分解後所有質因子的個數,要求num[gcd(a, b)] <= p的(a,b)的對數,其中1 <= a <= n,1 <= b <= m
題目分析:這題T了一天,先不考慮1,題目給的p的最大值是5e5,因此num[i]最大為18,因為2^19就大於5e5了
定義f(d)為gcd(a,b) = d的個數,g(d)為gcd(a,b) = d的倍數的個數,顯然g(d)很好求,就是(n / d) * (m / d)
又g(d) = f(d) + f(2d) + f(3d) + ...對此式進行莫比烏斯反演得到
f(d) = u(1)g(d) + u(2)g(2d) + u(3)g(3d) + ...,最後答案為Σu(k)g(kd),此時若直接列舉d,就算計算f(d)用分塊求和優化成接近sqrt(n),n*sqrt(n)接近2e8肯定超時,因此要換別的思路,考慮到num[i]最大隻有18,我們可以預處理出以i為最大公約數,且分解i後質因子個數等於num[i]的方案數,根據公式有sum[ki][num[i]] += u[k],令j=ki,則sum[j][num[i]] += u[j / i],注意這裡算的只是莫比烏斯函式的貢獻值,
舉個例子,比如
f(2) = u(1)g(2) + u(2)g(4) + u(3)g(6) + ...
f(3) = u(1)g(3) + u(2)g(6) + u(3)g(9) + ...
答案肯定要把它們加起來,注意到g(6)出現了兩次,可以理解為6這個數字對num[i] = 1的情況有兩次貢獻, 因此可以寫成(u(2) + u(3)) * g(6)
然後再處理分解i後質因子個數小於等於num[i]的方案數,最後再處理以i為最大公約數的字首和,預處理工作就結束了,複雜度為nlogn,線上計算時用分塊求和優化,複雜度為qsqrt(n),總的複雜度大概為nlogn+qsqrt(n)
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
using namespace std;
int const MAX = 5e5 + 5;
int n, m, p, pnum;
int mob[MAX], pr[MAX], sum[MAX][20];
int num[MAX];
bool prime[MAX];
void Mobius()
{
pnum = 0;
memset(prime, true, sizeof(prime));
mob[1] = 1;
for(int i = 2; i < MAX; i++)
{
if(prime[i])
{
pr[pnum ++] = i;
num[i] = 1;
mob[i] = -1;
}
for(int j = 0; j < pnum && i * pr[j] < MAX; j++)
{
num[i * pr[j]] = num[i] + 1;
prime[i * pr[j]] = false;
if(i % pr[j] == 0)
{
mob[i * pr[j]] = 0;
break;
}
mob[i * pr[j]] = -mob[i];
}
}
}
void Init()
{
Mobius();
for(int i = 1; i < MAX; i++)
for(int j = i; j < MAX; j += i)
sum[j][num[i]] += mob[j / i];
for(int i = 1; i < MAX; i++)
for(int j = 1; j < 19; j++)
sum[i][j] += sum[i][j - 1];
for(int i = 1; i < MAX; i++)
for(int j = 0; j < 19; j++)
sum[i][j] += sum[i - 1][j];
}
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][p] - sum[i - 1][p]);
}
return ans;
}
int main()
{
Init();
int T;
scanf("%d", &T);
while(T --)
{
scanf("%d %d %d", &n, &m, &p);
printf("%lld\n", p > 18 ? (ll) n * m : cal(n, m));
}
}
相關文章
- HDU 1695 GCD (容斥 + 莫比烏斯反演)GC
- 莫比烏斯反演
- HDU 5212 Code (容斥 莫比烏斯反演基礎題)
- Hackerrank GCD Product(莫比烏斯反演)GC
- BZOJ 3309 DZY Loves Math (莫比烏斯反演的應用 好題)
- 莫比烏斯反演學習筆記筆記
- 比較典的莫比烏斯反演
- 狄利克雷卷積 & 莫比烏斯反演卷積
- ZOJ 3868 GCD Expectation (容斥+莫比烏斯反演)GC
- POJ 3904 Sky Code (容斥+莫比烏斯反演)
- 狄利克雷卷積與莫比烏斯反演卷積
- BZOJ 2818 Gcd (莫比烏斯反演 或 尤拉函式)GC函式
- 演算法隨筆——數論之莫比烏斯反演演算法
- 洛谷 P2257 YY的GCD(莫比烏斯反演)GC
- Codeforces 548E Mike and Foam (容斥+莫比烏斯反演)
- CSU 1325 A very hard problem (莫比烏斯反演+分塊求和優化)優化
- SPOJ VLATTICE Visible Lattice Points (莫比烏斯反演基礎題)
- ZOJ 3435 Ideal Puzzle Bobble (莫比烏斯反演基礎題)Idea
- Codeforces 235E Number Challenge (神定理+莫比烏斯反演)
- SPOJ PGCD - Primes in GCD Table (好題! 莫比烏斯反演+分塊求和優化)GC優化
- FZU 1969 && UVA 11426 GCD Extreme (尤拉函式 或 莫比烏斯反演)GCREM函式
- 並查集的應用:hdu 1213並查集
- hdu4268 multiset應用 貪心
- HDU 5438 Ponds (拓撲排序應用+DFS)排序
- hdu4400 STL應用 查詢思維題
- HDU 3501 Calculation 2 (尤拉函式應用)函式
- BZOJ 2301 [HAOI2011]Problem b (容斥+莫比烏斯反演+分塊優化 詳解)優化
- HDU3530 單調佇列的應用佇列
- HDU 4349 Xiao Ming's Hope (Lucas定理的應用)
- hdu1251 字典樹的應用(查詢公共字首)
- HDU 1222 Wolf and Rabbit (擴充套件歐幾里德應用)套件
- lg容斥與反演
- 莫比烏斯函式函式
- 二項式反演小記
- Pytorch實現波阻抗反演PyTorch
- Binary Tree Traversals(HDU1710)二叉樹的簡單應用二叉樹
- X問題(中國剩餘定理+不互質版應用)hdu1573
- hdu 2085 java 核反應堆Java