HDU 4746 Mophues (莫比乌斯反演应用)
来源:互联网 发布:ubuntu ftp服务器搭建 编辑:程序博客网 时间:2024/05/28 19:24
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.
210 10 010 10 1
6393
2013 ACM/ICPC Asia Regional Hangzhou Online
题目链接: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 longusing 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)); }}
0 0
- HDU 4746 Mophues (莫比乌斯反演应用)
- HDU 4746 Mophues (莫比乌斯反演应用)
- hdu 4746 Mophues 莫比乌斯反演
- HDU 4746 Mophues(莫比乌斯反演)
- HDU 4746 Mophues(莫比乌斯反演)
- HDU 4746 Mophues【莫比乌斯反演】
- HDU 4746-Mophues (莫比乌斯反演)
- HDU4746 Mophues(莫比乌斯反演)
- HDU 4746 Mophues(有趣的前缀和/莫比乌斯反演)
- hdu 4746 Mophues (莫比乌斯反演 + 分块+线性筛)
- hdu4746 Mophues(莫比乌斯反演)-好题
- HDU 4746 Mophues 莫比乌斯第三弹
- hdu 4746 Mophues 莫比乌斯 分块优化
- hdu 1695 莫比乌斯反演
- hdu 5072 莫比乌斯反演
- hdu 1695 莫比乌斯反演
- hdu 1695 莫比乌斯反演
- HDU 5656 (莫比乌斯反演)
- 系统日志Logrotate配置
- 【算法】Sky Map
- HDU 5416(思路题目)
- C++ map的基本操作和使用
- Hadoop简介(分布式系统基础架构)
- HDU 4746 Mophues (莫比乌斯反演应用)
- iOS中使用storyboard实现页面跳转,Segue详解及简单的数据传递
- UVA 10815 Andy's First Dictionary
- 设置元素的属性attr 和setAttribute
- 开源平台选型建议
- [iOS备忘录]UITextView多行输入,键盘隐藏问题[swift]
- Linux命令(1)
- linux c语言将系统调用的执行结果赋给变量
- java线程的同步方法