ACM学习历程—HDU4746 Mophues(莫比乌斯)
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.
Input
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×10 5. Q
<=5000).
Output
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.
Sample Input
2
10 10 0
10 10 1
Sample Output
63
93
题目大意就是求k <= p,满足gcd(x, y) == k的对数。
首先可以预处理出任意数i其质因子个数luck[i]。
这个的话可以初始化luck[1] = 0,然后类似于bfs的过程,把当前i能到达的状态prime*i标记,即luck[prime*i] = luck[i]+1。然后用vis数组来避免重复标记。
然后就是根据莫比乌斯,之前写过类似的题解,结论就是gcd(x, y) == k的对数f(k)满足:
f(k) = sum(u(j/k)*(m/j)*(n/j))
(k | j)
这样对于满足的k,就是上式的k求和,之前也说过sum(sum(u(j/k)*(m/j)*(n/j)) (k | j))中两个sum的次序可以进行交换的。因为一个k对应好多j,等同于一个j对应好多k。
这样就是求满足条件的k的sum((m/j)*(n/j)*sum(u(j/k))) (k | j)
这样可以预先处理出所有j对应的sum(u(j/k)),
但是还不够,这样对于重复的p,会重复计算,这样需要多开一维sum(p, u(j/k))表示满足p条件下的sum,相当于把所有情况的sum离线下来。这样做主要的前提是p很小,因为5*10^5内质因子的个数最多有log2(5*10^5)个,大约18个。
在求sum[p][j]时,可以先计算出gcd(x, y) = p的情况,然后求前缀和就是gcd(x, y) <= p的情况了。
不过这题到这里为止还没有结束。。。
预处理复杂度能过去,不过后面的数据规模比较大,O(n)时间内过不去。
需要对上述答案进行分组加速。
因为对于n/j来说,必然会存在一种情况,n/j == n/(j+1) = …..
就是连续的几个j的结果一致,因为这里的除法取的是下整。
这样的话,若n/j == p,
那么p*j
<= n < (p+1)*j
如果x也满足n/j == n/x == p
那么自然p*x
<= n < (p+1)*x
于是x
<= n/p。
也就是x最大可以取n/p,由于取的是下整,可以放心取等号。
那么从j到n/(n/j)区间内的n/j的结果都是一致的。然后j到m/(m/j)的m/j的结果又是一致的。
自然从j到min(n/(n/j), m/(m/j))内(n/j)*(m/j)的结果一致。
那么这一段应该直接计算sum[p](j~ min(n/(n/j), m/(m/j)))* (n/j)*(m/j),然后可以事先对sum[p][j]求和,就可以通过作差求出前半段。
最后需要注意的一点是当p >= log2(len)时,所有(x, y)对就都能满足条件了,答案自然是m*n。
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <queue>
#define LL long long using namespace std; const int maxN = ;
int n, m, p;
int luck[maxN], sum[][maxN];
int prime[maxN], cnt, u[maxN];
bool vis[maxN]; void mobius()
{
memset(vis, false,sizeof(vis));
u[] = ;
cnt = ;
for(int i = ; i < maxN; i++)
{
if(!vis[i])
{
prime[cnt++] = i;
u[i] = -;
}
for(int j = ; j < cnt && i*prime[j] < maxN; j++)
{
vis[i*prime[j]] = true;
if(i%prime[j])
u[i*prime[j]] = -u[i];
else
{
u[i*prime[j]] = ;
break;
}
}
}
} void calLuck()
{
memset(vis, false, sizeof(vis));
luck[] = ;
queue<int> q;
q.push();
vis[] = true;
int k, v;
while (!q.empty())
{
k = q.front();
q.pop();
for (int i = ; i < cnt; ++i)
{
if ((LL)prime[i]*k >= maxN)
break;
v = prime[i]*k;
if (!vis[v])
{
luck[v] = luck[k]+;
q.push(v);
vis[v] = true;
}
}
}
} void init()
{
mobius();
calLuck();
memset(sum, false, sizeof(sum));
//计算sum[p][j]的值,gcd个数为p的i的倍数j系数的总和
for (int i = ; i < maxN; ++i)
{
for (LL j = i; j < maxN; j += i)
sum[luck[i]][j] += u[j/i];
}
//计算sum[p][j]的值,gcd个数小于等于p的i的倍数j系数的总和
for (int i = ; i < maxN; ++i)
{
for (int k = ; k < ; ++k)
sum[k][i] += sum[k-][i];
}
//计算sum[p][j]的j前缀和,用于分组加速
for (int k = ; k < ; ++k)
for (int i = ; i < maxN; ++i)
sum[k][i] += sum[k][i-];
} void work()
{
int len = min(m, n);
if (p >= log2(len))
{
printf("%I64d\n", (LL)m*n);
return;
}
LL ans = ;
for (int i = , j; i <= len; i = j+)
{
j = min(n/(n/i), m/(m/i));
ans += (LL)(sum[p][j]-sum[p][i-])*(m/i)*(n/i);
}
printf("%I64d\n", ans);
} int main()
{
//freopen("test.in", "r", stdin);
init();
int T;
scanf("%d", &T);
for (int times = ; times <= T; ++times)
{
scanf("%d%d%d", &n, &m, &p);
work();
}
return ;
}
ACM学习历程—HDU4746 Mophues(莫比乌斯)的更多相关文章
- hdu4746 Mophues 莫比乌斯
/** 题目:hdu4746 Mophues 链接:http://acm.hdu.edu.cn/showproblem.php?pid=4746 题意:求x,y在给定范围内gcd(x,y)分解素因子的 ...
- ACM学习历程—ZOJ 3868 GCD Expectation(莫比乌斯 || 容斥原理)
Description Edward has a set of n integers {a1, a2,...,an}. He randomly picks a nonempty subset {x1, ...
- ACM学习历程—HDU4675 GCD of Sequence(莫比乌斯)
Description Alice is playing a game with Bob. Alice shows N integers a 1, a 2, …, a N, and M, K. She ...
- ACM学习历程—POJ3090 Visible Lattice Points(容斥原理 || 莫比乌斯)
Description A lattice point (x, y) in the first quadrant (x and y are integers greater than or equal ...
- ACM学习历程—HDU1695 GCD(容斥原理 || 莫比乌斯)
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) = ...
- ACM学习历程—HYSBZ 2818 Gcd(欧拉函数 || 莫比乌斯反演)
Description 给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对. Input 一个整数N Output 如题 Sample Input 4 Sam ...
- 完成了C++作业,本博客现在开始全面记录acm学习历程,真正的acm之路,现在开始
以下以目前遇到题目开始记录,按发布时间排序 ACM之递推递归 ACM之数学题 拓扑排序 ACM之最短路径做题笔记与记录 STL学习笔记不(定期更新) 八皇后问题解题报告
- ACM学习历程—HDU 5512 Pagodas(数学)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5512 学习菊苣的博客,只粘链接,不粘题目描述了. 题目大意就是给了初始的集合{a, b},然后取集合里 ...
- ACM学习历程—HDU5521 Meeting(图论)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5521 学习菊苣的博客,只粘链接,不粘题目描述了. 题目大意就是一个人从1开始走,一个人从n开始走.让最 ...
随机推荐
- socket java 实例
简单的java socket 示例 一.搭建服务器端 a).创建ServerSocket对象绑定监听端口. b).通过accept()方法监听客户端的请求. c).建立连接后,通过输入输出流读取客户端 ...
- jvm本身的多线程机制
1 多线程环境下的构造函数调用 构造函数本身并没有隐式的同步,因为各个线程构建的是自己的对象,它们之间是不存在竞争关系的. 2 class loader在load class时被了sychronize ...
- php字符串操作: 去掉UTF-16的空格
$s = json_encode($s); $s = str_replace('\u00a0','',$s); $s = str_replace('\u3000','',$s); $s = str_r ...
- CentOS6安装DaoCloud加速器
天朝的网,你又不是不懂.我最爱的红杏最近也用不了了.FUCK GFW. 在这,我们使用DaoCloud的加速器,打开网址 https://dashboard.daocloud.io/mirror 找到 ...
- python利用wxpy监控微信公众号
此次利用wxpy可以进行微信公众号的消息推送监测(代码超级简单),这样能进行实时获取链接.但是不光会抓到公众号的消息,好友的消息也会抓到(以后会完善的,毕竟现在能用了,而且做项目的微信号肯定是没有好友 ...
- 用 Java 技术创建 RESTful Web 服务
JAX-RS:一种更为简单.可移植性更好的替代方式 JAX-RS (JSR-311) 是一种 Java™ API,可使 Java Restful 服务的开发变得迅速而轻松.这个 API 提供了一种基于 ...
- ssh允许root用户登陆
新的系统无root用户密码,设置root用户密码,修改也是这么修改 sudo passwd root 连续输入两次新密码. 允许root用户登陆: /etc/ssh/sshd_config 找到 Pe ...
- TCP/IP 简介
1: 什么是 TCP/IP? TCP/IP 是供已连接因特网的计算机进行通信的通信协议. TCP/IP 指传输控制协议/网际协议 (Transmission Control Protocol / In ...
- ps 切片 蓝色 灰色 小标志 什么意思
切片颜色 区分自动切片与用户切片和基于图层的切片.默认情况下,用户切片和基于图层的切片带蓝色标记,而自动切片带灰色标记.-----用户切片就是你需要的切片,其他区域会形成自动切片,可以视为自己不要的, ...
- 剑指offer——树中两个节点的最低公共祖先
代码来源与<剑指offer> 得到从根节点开始到输入的两个结点的两条,需要遍历两次树,每遍历一次的时间复杂度是O(n),得到的两条路径的长度在最差情况时是O(n),通常情况下两条路径的长度 ...