题目大意:

给定n,m,求有多少组(a,b) 0<a<=n , 0<b<=m , 使得gcd(a,b)= p , p是一个素数

这里本来利用枚举一个个素数,然后利用莫比乌斯反演可以很方便得到答案,但是数据量过大,完全水不过去

题目分析过程(从别人地方抄来的)

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)可以在线性筛素数的时候算出。剩下的就是前缀和、分块了。

然后自己看了很久才表示看懂- - ,这里加上自己的理解更加便于阅读

因为我们根据线性筛法得到的莫比乌斯函数,欧拉函数这样的积性函数

所以我们也总是希望上方的g(x)也可以是积性函数方便在线性时间内计算出答案

对于一个积性函数来说,总是不断往前判断它乘上一个素数和当前的联系

列一个素数 p' 那么g(p'x)的结果分析

线性筛的中间过程总是判断当前 i % prime[j] 是否等于 0 , 所以这里也是判断当前x和p'的整除关系

1.x%p' = 0  , 那么说明x中必然有一个p'的因子 , 那么sigma(p | p'x, μ(p'x/p)) 中,如果列举的p!=p' , 说明此时 p'*p' | (p'*x/p) ,也就是有至少2个p'的素数因子,所以

mu[p'*x/p] = 0 , 唯一就只要考虑 p 取到 p'的时候  mu[p'*x/p] = mu[x] , 因为其他mu[]都为0->g(p'x)=mu[x]

2.x%p'!=0 , 那么对于先前所有的 x/p 来说,此时乘了p'  , 若p!=p' , 那么因为多了一个因子 mu[p'*x/p] = -mu[x/p] , 所以在p!=p'时,所有的情况相加为-g(x),

在考虑枚举到的p'=p , mu[p'*x/p]  = mu[x] , 所以所有答案叠加所得就是 -g[x]+mu[x]

 #include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int MAXN = ;
#define ll long long
int mu[MAXN+] , prime[MAXN/] , g[MAXN+] , sum[MAXN+];
bool check[MAXN+];
int tot; void getMu(int n)
{
memset(check , , sizeof(check));
tot=;
check[] = true , mu[]= , g[]=;
for(int i= ; i<=n ; i++){
if(!check[i]) prime[tot++]=i , mu[i]=- , g[i]=;
for(int j= ; j<tot ; j++){
if(i*prime[j]>n) 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[]=g[];
for(int i= ; i<=n ; i++) sum[i]=g[i]+sum[i-];
} void swap(int &x , int &y)
{
int t=x;
x=y , y=t;
} int main()
{
// freopen("a.in" , "r" , stdin);
getMu(MAXN);
int T , n , m;
scanf("%d" , &T);
while(T--)
{
scanf("%d%d" , &n , &m);
if(n>m) swap(n , m);
ll ans = ;
int la=;
for(int s= ; s<=n ; s=la+){
//这里分块的意思很明显,因为在一个区间内,n/s ,m/s 的取值是不会变的,所以我们不用连续计算
la = min(n/(n/s) , m/(m/s));
ans = ans + (ll)(n/s)*(m/s)*(sum[la]-sum[s-]);
}
printf("%lld\n" , ans);
}
return ;
}

* SPOJ PGCD Primes in GCD Table (需要自己推线性筛函数,好题)的更多相关文章

  1. SPOJ - PGCD Primes in GCD Table(莫比乌斯反演)

    http://www.spoj.com/problems/PGCD/en/ 题意: 给出a,b区间,求该区间内满足gcd(x,y)=质数的个数. 思路: 设f(n)为 gcd(x,y)=p的个数,那么 ...

  2. SPOJ PGCD 4491. Primes in GCD Table && BZOJ 2820 YY的GCD (莫比乌斯反演)

    4491. Primes in GCD Table Problem code: PGCD Johnny has created a table which encodes the results of ...

  3. SPOJ4491. Primes in GCD Table(gcd(a,b)=d素数,(1&lt;=a&lt;=n,1&lt;=b&lt;=m))加强版

    SPOJ4491. Primes in GCD Table Problem code: PGCD Johnny has created a table which encodes the result ...

  4. PGCD2 - Primes in GCD Table (Hard)

    这题肝了三四天,其他啥也没做... 传送门 然后...双倍经验 简单版 不知道为什么会脑抽去帮 LZ_101 大佬验题... 题目和被 A 穿的 PGCD 一样,数据范围变成大概 2e11 ... 于 ...

  5. SPOJ-PGCD Primes in GCD Table

    题目链接:https://vjudge.net/problem/SPOJ-PGCD 题目大意: 给定 \(N\) 和 \(M\),求满足 \((1 \le x \le N), (1 \le y \le ...

  6. Luogu2257 YY的GCD/BZOJ2818 Gcd加强版(莫比乌斯反演+线性筛)

    一通套路之后得到 求出中间那个函数的前缀和的话就可以整除分块了. 暴力求的话复杂度其实很优秀了,大约在n~nlogn之间. 不过可以线性筛做到严格线性.考虑其最小质因子,如果是平方因子那么只有其有贡献 ...

  7. SPOJ PGCD(莫比乌斯反演)

    传送门:Primes in GCD Table 题意:给定两个数和,其中,,求为质数的有多少对?其中和的范围是. 分析:这题不能枚举质数来进行莫比乌斯反演,得预处理出∑υ(n/p)(n%p==0). ...

  8. Codeforces Round #323 (Div. 2) C.GCD Table

    C. GCD Table The GCD table G of size n × n for an array of positive integers a of length n is define ...

  9. Codeforces Round #323 (Div. 1) A. GCD Table

    A. GCD Table time limit per test 2 seconds memory limit per test 256 megabytes input standard input ...

随机推荐

  1. 数学 SCU 4436 Easy Math

    题目传送门 /* 数学题:当有一个数开根号后是无理数,则No */ #include <cstdio> #include <algorithm> #include <cs ...

  2. win10系统下使用EDGE浏览器找不到Report Builder 启动图标

    Win10系统下如果要使用Report Builder,可能存在EDGE浏览器或者Chrome找不到ReportBuilder的启动图标的情况,此时,应以管理员权限运行IE浏览器,即可看到图标.

  3. js阻塞ui进程涉及的知识点整理

    项目进行中遇到了同步ajax阻塞ui线程阻塞的问题,原因是执行两个同步ajax请求为一次完整的方法,因业务需求需要循环执行这个方法,检查后台返回的数据正确,但是由于ajax请求时间过长,考虑增加遮罩层 ...

  4. matlab化简符号表达式

    化简符号表达式计算机毕竟还是挺笨的, 经过一系列的符号计算后, 得到的结果可能只有它自己才能看懂, Matlab提供大量函数以用于符号表达式的化简. collect(f): 函数用途是合并多项式中相同 ...

  5. leetcode_378. Kth Smallest Element in a Sorted Matrix_堆的应用

    Given a n x n matrix where each of the rows and columns are sorted in ascending order, find the kth ...

  6. COMMENT - 定义或者改变一个对象的评注

    SYNOPSIS COMMENT ON { TABLE object_name | COLUMN table_name.column_name | AGGREGATE agg_name (agg_ty ...

  7. 修改phpadmin中的默认超时时间

    登录后1440秒未活动后总是自动退出,一天还要登录多次,终于有时间来解决这个问题了,感觉是session超时,结果在网上search了下,找到解决办法啦,哈哈哈,在此做个笔记: phpmyadmin在 ...

  8. 用闭包方式实现点击a标签弹也索引值

    var self = document.getElementsByTagName("a"); for(var i=0;i<self.length;i++){ self[i]. ...

  9. 雷林鹏分享:PHP Secure E-mails

    在上一节中的 PHP e-mail 脚本中,存在着一个漏洞. PHP E-mail 注入 首先,请看上一章中的 PHP 代码: if (isset($_REQUEST['email'])) { // ...

  10. bootstrap-table的一些基本使用及表内编辑的实现

    最近工作需要接触了bootstrap-table 所以研究了一下,并做了笔记,红色位置要特别注意 前端主要使用了 jquery bootstrap-table  bootstrap-edittable ...