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
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.
Input
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).
Output
Sample Input
2
10 10 0
10 10 1
Sample Output
63
93
Source
题目链接: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 4746 Mophues (莫比乌斯反演应用)的更多相关文章
- hdu 4746 Mophues 莫比乌斯反演+前缀和优化
Mophues 题意:给出n, m, p,求有多少对a, b满足gcd(a, b)的素因子个数<=p,(其中1<=a<=n, 1<=b<=m) 有Q组数据:(n, m, ...
- HDU 4746 Mophues 莫比乌斯反演
分析: http://blog.csdn.net/acdreamers/article/details/12871643 分析参见这一篇 http://wenku.baidu.com/view/fbe ...
- Mophues HDU - 4746 (莫比乌斯反演)
Mophues \[ Time Limit: 10000 ms\quad Memory Limit: 262144 kB \] 题意 求出满足 \(gcd\left(a,b\right) = k\), ...
- HDU - 4746预处理莫比乌斯反演
链接 求[1,n] 和 [1,m]中有多少对数的GCD的素因子个数小于等于p 直接暴力做特定超时,所以我们想办法预处理,对于p大于18(1到5e5的最大素数因子个数)的情况,每一对都满足条件,O(1) ...
- HDU 4746 Mophues【莫比乌斯反演】
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4746 题意: 1≤x,y≤n , 求gcd(x,y)分解后质因数个数小于等k的(x,y)的对数. 分 ...
- HDU 4746 Mophues(莫比乌斯反演)题解
题意: \(Q\leq5000\)次询问,每次问你有多少对\((x,y)\)满足\(x\in[1,n],y\in[1,m]\)且\(gcd(x,y)\)的质因数分解个数小于等于\(p\).\(n,m, ...
- hdu.5212.Code(莫比乌斯反演 && 埃氏筛)
Code Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submi ...
- hdu 1695 GCD 莫比乌斯反演入门
GCD 题意:输入5个数a,b,c,d,k;(a = c = 1, 0 < b,d,k <= 100000);问有多少对a <= p <= b, c <= q <= ...
- HDU 1695 GCD 莫比乌斯反演
分析:简单的莫比乌斯反演 f[i]为k=i时的答案数 然后就很简单了 #include<iostream> #include<algorithm> #include<se ...
随机推荐
- hdu5985[概率dp] 2016青岛icpc现场赛
#include <bits/stdc++.h> using namespace std; ][]; ][]; ][]; ]; ]; int T, n; double fastpow(do ...
- ABC128F Frog Jump
题目链接 题目大意 给定一个长为 $n$ 的数组 $s$,下标从 $0$ 开始.$ 3 \le n \le 10^5$,$-10^9 \le s_i \le 10^9$,$s_0 = s_{n - 1 ...
- [ZJOI2010][bzoj1834] 网络扩容 [费用流]
题面 传送门 思路 第一问:无脑网络流跑一波 第二问: 先考虑一个贪心的结论:扩容出来的扩容流量一定要跑满 证明显然 因此我们可以把扩容费用可以换个角度思考,变成增加一点流量,花费W的费用 这样,我们 ...
- redis学习(五)事务
事务是一个单独的隔离操作:事务中的所有命令都会序列化.按顺序地执行.事务在执行的过程中,不会被其他客户端发送来的命令请求所打断. 1.事务基本命令: multi:标记一个事务块的开始 exec:执行所 ...
- [CODEVS2035]机票打折问题
题目描述 Description .输入机票原价(3到4位的正整数,单位:元),再输入机票打折率(小数点后最多一位数字).编程计算打折后机票的实际价格(单位:元.计算结果要将个位数四舍五入到十位数“元 ...
- SQL优化 ASP.NET ADO.NET
原文发布时间为:2009-08-26 -- 来源于本人的百度文章 [由搬家工具导入] 总的考虑方向 1) 根据数据使用的方式来设计数据访问层 2) 缓存数据,避免不必要的操 ...
- Zookeeper如何从官网下载和安装
打开百度搜索,输入Zookeeper关键词,一般第一条搜索记录就是apache官网下载的地址 进入apache官网,由于是国外的网站,里面内容都是英文的,可以大概看下Zookeeper的描述和介绍,在 ...
- 安装python 2.7
安装包下载地址 windows:https://www.python.org/ftp/python/2.7.14/python-2.7.14.amd64.msi linux: https://www. ...
- LeetCode OJ-- Count and Say
https://oj.leetcode.com/problems/count-and-say/ 求经过n次变换后,变成了什么. 1 11 21 1211 111221 ps. 3 变成 ‘3 ...
- Android Studio 打开后无故爆红后解决办法
今天打开AndroidSutudio后表示一脸蒙蔽,项目无故爆红,我本以为是哪里的代码有错导致 报错,于是乎逐个检查,但是并没有发现任何问题,然后CelarProduct,ReBuildProduct ...