4491. Primes in GCD Table

Problem code: PGCD

Johnny has created a table which encodes the results of some operation -- a function of two arguments. But instead of a boring multiplication table of the sort you learn by heart at prep-school, he has created a GCD (greatest common divisor) table! So he now has a table (of height a and width b), indexed from (1,1) to (a,b), and with the value of field (i,j) equal to gcd(i,j). He wants to know how many times he has used prime numbers when writing the table.

Input

First, t ≤ 10, the number of test cases. Each test case consists of two integers, 1 ≤ a,b < 107.

Output

For each test case write one number - the number of prime numbers Johnny wrote in that test case.

Example

Input:
2
10 10
100 100
Output:
30
2791

题解参考:

http://quartergeek.com/eight-gcd-problems/

ans = sigma(p, sigma(d, μ(d) * (n/pd) * (m/pd)))

Let s = pd, then

ans = sigma(s, sigma(p, μ(s/p) * (n/s) * (m/s)))
= sigma(s, (n/s) * (m/s) * sigma(p, μ(s/p))) Let g(x) = sigma(p, μ(x/p)), then ans = sigma(s, (n/s) * (m/s) * g(s))

如果我们能预处理g(x)的话就能和前面一样分块搞了。这个时候我们多么希望g(x)μ(x)一样是积性函数。看完题解后,发现有一个不是积性函数,胜似积性函数的性质。由于题解没有给证明,所以就意淫了一个证明。

考虑质数p'g(p'x) = sigma(p | p'x, μ(p'x/p))

  • x % p' == 0,那么考虑sigma中的变量p的所有取值,它和g(x)p是相同的。而μ(x)这个函数,如果x有平方因子的话就等于0,因此当p != p'μ(p'x/p) = 0,当p == p'是,μ(p'x/p) = μ(x)。所以g(p'x) = μ(x)
  • x % p' != 0,同样考虑p,会发现它的取值只比g(x)中的p多出一个p'。同理按照p是否等于p'讨论,可以得到g(p'x) = -g(x) + μ(x)

因此g(x)可以在线性筛素数的时候算出。剩下的就是前缀和、分块了。

 /* ***********************************************
Author :kuangbin
Created Time :2013-10-19 22:01:05
File Name :E:\2013ACM\专题学习\数学\莫比乌斯反演\SPOJ_PGCD.cpp
************************************************ */ #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
using namespace std; const int MAXN = ;
bool check[MAXN+];
int prime[MAXN+];
int mu[MAXN+];
int g[MAXN+];
int sum[MAXN+];
void Moblus()
{
memset(check,false,sizeof(check));
mu[] = ;
int tot = ;
for(int i = ; i <= MAXN; i++)
{
if(!check[i])
{
prime[tot++] = i;
mu[i] = -;
g[i] = ;
}
for(int j = ;j < tot;j++)
{
if(i * prime[j] > MAXN)break;
check[i*prime[j]] = true;
if(i % prime[j] == )
{
mu[i * prime[j]] = ;
g[i * prime[j]] = mu[i];
break;
}
else
{
mu[i * prime[j]] = -mu[i];
g[i * prime[j]] = -g[i] + mu[i];
}
}
}
sum[] = ;
for(int i = ;i <= MAXN;i++)
sum[i] = sum[i-] + g[i];
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
Moblus();
int T;
int n,m;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
if(n > m)swap(n,m);
long long ans = ;
int last = ;
for(int i = ;i <= n;i = last+)
{
last = min(n/(n/i),m/(m/i));
ans += (long long)(sum[last] - sum[i-])*(n/i)*(m/i);
}
printf("%lld\n",ans);
}
return ;
}

最新文章

  1. MVC下压缩输入的HTML内容
  2. Oracle数据库,数据的增、删、改、查
  3. python之I/O操作
  4. ROS 新手教程 命令汇总
  5. 【POI】使用POI处理xlsx的cell中的超链接 和 插入图片 和 设置打印区域
  6. RabbitMQ学习总结 第五篇:路由Routing
  7. Javascript模块规范(CommonJS规范&amp;&amp;AMD规范)
  8. Solr4.8.0源码分析(22)之SolrCloud的Recovery策略(三)
  9. uva 1378 A Funny Stone Game (博弈-SG)
  10. go使用rpc
  11. LeetCode算法题-Lowest Common Ancestor of a Binary Search Tree
  12. TF:TF下CNN实现mnist数据集预测 96%采用placeholder用法+2层C及其max_pool法+隐藏层dropout法+输出层softmax法+目标函数cross_entropy法+AdamOptimizer算法
  13. 画一条0.5px的线
  14. CSS样式定义的优先级顺序总结
  15. PaaS服务之路漫谈(三)
  16. NYOJ-61 传纸条(一)
  17. CAN总线的学习
  18. 无法找到 ContextLoaderListener 类
  19. live555源码分析
  20. JMessage Android 端开发详解

热门文章

  1. &lt;header&gt;&lt;footer&gt;引用
  2. 华中邀请赛现场赛F题 Seats
  3. Floyd判圈算法 UVA 11549 - Calculator Conundrum
  4. Requests中出现大量ASYNC_NETWORK_IO等待
  5. 工具类。父类(Pom文件)
  6. 关于Hadoop未授权访问可导致数据泄露通知
  7. oracle数据库查询重复记录
  8. 002_docker构建zookeeper环境
  9. 初始ASP.NET数据控件【续 DataList】
  10. Promise初探