BZOJ2301: [HAOI2011]Problem b[莫比乌斯反演 容斥原理]【学习笔记】

时间:2022-09-23 00:00:08

2301: [HAOI2011]Problem b

Time Limit: 50 Sec  Memory Limit: 256 MB
Submit: 4032  Solved: 1817
[Submit][Status][Discuss]

Description

对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数。

Input

第一行一个整数n,接下来n行每行五个整数,分别表示a、b、c、d、k

Output

共n行,每行一个整数表示满足要求的数对(x,y)的个数

Sample Input

2

2 5 1 5 1

1 5 1 5 2

Sample Output

14

3

HINT

100%的数据满足:1≤n≤50000,1≤a≤b≤50000,1≤c≤d≤50000,1≤k≤50000


研究了好长时间差不多明白了,第一道莫比乌斯反演,好多值得学习的东西

首先,由容斥原理易得答案为

cal(b,d,k)-cal(a-1,d,k)-cal(b,c-1,k)+cal(a-1,c-1,k)

  • 这个问题等价于询问有多少个数对(x,y)满足1<=x<=[n/k],1<=y<=[m/k]且x与y互质
  • 考虑莫比乌斯反演,
  • f(i)为1<=x<=n,1<=y<=m且gcd(x,y)=i的数对(x,y)的个数
  • F(i)为1<=x<=n,1<=y<=m且i|gcd(x,y)的数对(x,y)的个数
  • 显然,F(i)=(n/i)*(m/i) 整除,并且F(i)=Σ{i|d} f(d) 是倍数和
  • 反演后,f(i)=Σ{i|d} miu(d/i)*F(d)=Σ{i|d} miu(d/i)*(n/d)*(m/d)
  • 但这样每个询问复杂度是O(n)
  • 观察式子,发现[n/d] 最多有2sqrt(n) 个取值(整除....一段相同 参考链接)
  • 那么 (n/d)*(m/d)就至多有2sqrt(n)+2sqrt(m)个取值 (当然不是乘起来,因为对于一个n只有一个值而不是2sqrt(n)个)
  • 计算每个询问时枚举这2sqrt(n)+2sqrt(m)个取值,因为一个取值是一段,要乘一段miu的和,所以对莫比乌斯函数维护一个前缀和,就可以在sqrt(n)时间内出解

【WT1(WT是从小新那里学来的....发现竟然是问题的首字母):】

f(k)=Σ{k|d} miu(d/k)*(n/d)*(m/d)这个式子怎么计算?

d是k的倍数,取值k,2*k,3*k,...,t*k

f(k)=Σ{i=1..n/k} miu(i)*(n/(k*i))*(m/(k*i))   //注意,【整除满足 x/a/b=a/(a*b)】

更一般的:

f(k)=Σ{k|d} miu(d/k)*F(d)

--> f(k)=Σ{i=1..n/k}miu(i)*F(i*k)

 【WT2 】如何按照整除取值相同分段?

当前除法为n/i,与它相同的上界到n/(n/i)

为什么?我想了好久,最后的方法是

考虑n是一段区间,n=p*i+q,被分成p段长为i的

i每增加1 q就减少p,(这时候整除的取值没有改变),最多能减少q/p个,那么此时i=i+q/p=(i*p+q)/p=n/(n/i)

注意:miu的区间和*(n/i)*(m/i)可能会溢出,对拍都没有发现.......

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=5e4+;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-; c=getchar();}
while(c>=''&&c<=''){x=x*+c-''; c=getchar();}
return x*f;
}
int n,a,b,c,d,k;
bool notp[N];
ll p[N],mu[N];
void sieve(){
mu[]=;
for(int i=;i<=N-;i++){
if(!notp[i]) p[++p[]]=i,mu[i]=-;
for(int j=;j<=p[]&&i*p[j]<=N-;j++){
int t=i*p[j];
notp[t]=;
if(i%p[j]==){
mu[t]=;
break;
}
mu[t]=-mu[i];
}
}
for(int i=;i<=N-;i++) mu[i]+=mu[i-];
}
ll cal(int n,int m,int k){
n/=k;m/=k;
if(n>m) swap(n,m);
ll ans=;int r=;
for(int i=;i<=n;i=r+){
r=min(n/(n/i),m/(m/i));
ans+=(mu[r]-mu[i-])*(n/i)*(m/i);
}
return ans;
}
int main(int argc, const char * argv[]) {
//freopen("in.txt","r",stdin);
//freopen("1.out","w",stdout);
sieve();
int T=read();
while(T--){
a=read();b=read();c=read();d=read();k=read();
printf("%lld\n",cal(b,d,k)-cal(a-,d,k)-cal(b,c-,k)+cal(a-,c-,k));
} return ;
}

附:还有另一种思考的角度,从莫比乌斯函数的角度考虑,殊途同归

复制鏼爷的题解

推导:

BZOJ2301: [HAOI2011]Problem b[莫比乌斯反演 容斥原理]【学习笔记】
BZOJ2301: [HAOI2011]Problem b[莫比乌斯反演 容斥原理]【学习笔记】
BZOJ2301: [HAOI2011]Problem b[莫比乌斯反演 容斥原理]【学习笔记】
用莫比乌斯函数的性质把求和的式子换掉,
BZOJ2301: [HAOI2011]Problem b[莫比乌斯反演 容斥原理]【学习笔记】
其中BZOJ2301: [HAOI2011]Problem b[莫比乌斯反演 容斥原理]【学习笔记】,更换求和指标,
BZOJ2301: [HAOI2011]Problem b[莫比乌斯反演 容斥原理]【学习笔记】
容易知道BZOJ2301: [HAOI2011]Problem b[莫比乌斯反演 容斥原理]【学习笔记】单调不上升,且最多有BZOJ2301: [HAOI2011]Problem b[莫比乌斯反演 容斥原理]【学习笔记】种不同的取值。所以按取值分成BZOJ2301: [HAOI2011]Problem b[莫比乌斯反演 容斥原理]【学习笔记】个段分别处理,一个连续段内的和可以用预处理出的莫比乌斯函数前缀和求出

BZOJ2301: [HAOI2011]Problem b[莫比乌斯反演 容斥原理]【学习笔记】的更多相关文章

  1. &lbrack;bzoj2301&rsqb;&lbrack;HAOI2011&rsqb;Problem B —— 莫比乌斯反演&plus;容斥原理

    题意 给定a, b, c, d, k,求出: \[\sum_{i=a}^b\sum_{j=c}^d[gcd(i, j) = k]\] 题解 为方便表述,我们设 \[calc(\alpha, \beta ...

  2. BZOJ2301&colon; &lbrack;HAOI2011&rsqb;Problem b 莫比乌斯反演

    分析:对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数. 然后对于求这样单个的gcd(x,y)=k的, ...

  3. BZOJ2301&colon;&lbrack;HAOI2011&rsqb;Problem b&lpar;莫比乌斯反演&comma;容斥&rpar;

    Description 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数. Input 第一行一个整数 ...

  4. &lbrack;HAOI2011&rsqb;&lbrack;bzoj2301&rsqb; Problem b &lbrack;莫比乌斯反演&plus;容斥原理&plus;分块前缀和优化&rsqb;

    题面: 传送门 有洛谷就尽量放洛谷链接呗,界面友好一点 思路: 和HDU1695比较像,但是这一回有50000组数据,直接莫比乌斯反演慢慢加的话会T 先解决一个前置问题:怎么处理a,c不是1的情况? ...

  5. &lbrack;BZOJ1101&amp&semi;BZOJ2301&rsqb;&lbrack;POI2007&rsqb;Zap &lbrack;HAOI2011&rsqb;Problem b&vert;莫比乌斯反演

    对于给定的整数a,b和d,有多少正整数对x,y,满足x<=a,y<=b,并且gcd(x,y)=d. 我们可以令F[n]=使得n|(x,y)的数对(x,y)个数 这个很容易得到,只需要让x, ...

  6. P2522 &lbrack;HAOI2011&rsqb;Problem b &lpar;莫比乌斯反演&rpar;

    题目 P2522 [HAOI2011]Problem b 解析: 具体推导过程同P3455 [POI2007]ZAP-Queries 不同的是,这个题求的是\(\sum_{i=a}^b\sum_{j= ...

  7. Bzoj 2301&colon; &lbrack;HAOI2011&rsqb;Problem b&lpar;莫比乌斯反演&plus;除法分块&rpar;

    2301: [HAOI2011]Problem b Time Limit: 50 Sec Memory Limit: 256 MB Description 对于给出的n个询问,每次求有多少个数对(x, ...

  8. BZOJ 2301&colon; &lbrack;HAOI2011&rsqb;Problem b 莫比乌斯反演

    2301: [HAOI2011]Problem b Time Limit: 50 Sec  Memory Limit: 256 MBSubmit: 1007  Solved: 415[Submit][ ...

  9. BZOJ&period;2301&period;&lbrack;HAOI2011&rsqb;Problem B&lpar;莫比乌斯反演 容斥&rpar;

    [Update] 我好像现在都看不懂我当时在写什么了=-= \(Description\) 求\(\sum_{i=a}^b\sum_{j=c}^d[(i,j)=k]\) \(Solution\) 首先 ...

随机推荐

  1. malloc原理和内存碎片

    当一个进程发生缺页中断的时候,进程会陷入内核态,执行以下操作: 1.检查要访问的虚拟地址是否合法 2.查找/分配一个物理页 3.填充物理页内容(读取磁盘,或者直接置0,或者啥也不干) 4.建立映射关系 ...

  2. 领导者&sol;追随者(Leader&sol;Followers)模型和半同步&sol;半异步(half-sync&sol;half-async)模型都是常用的客户-服务器编程模型

    领导者-追随者(Leader/Followers)模型的比喻 半同步/半异步模型和领导者/追随者模型的区别: 半同步/半异步模型拥有一个显式的待处理事件队列,而领导者-追随者模型没有一个显式的队列(很 ...

  3. js 获取url 参数

    $(function () { var WeixinCode = GetQueryString("WeixinCode"); $("#ProXQ").attr( ...

  4. Eclipse和PyDev搭建完美Python开发环境(Windows篇)(转)

      摘要:本文讲解了用Eclipse和PyDev搭建Python的开发环境. 十一长假在家闲着没事儿,准备花点时间学习一下Python. 今儿花了一个下午搭建Python的开发环境,不禁感叹————开 ...

  5. Android 插件化和热修复知识梳理

    概述 在Android开发中,插件化和热修复的话题越来越多的被大家提及,同时随着技术的迭代,各种框架的发展更新,插件化和热修复的框架似乎已经日趋成熟,许多开发者也把这两项技术运用到实际开发协作和正式的 ...

  6. mysql----SELECT names&sol;zh

    < SELECT names   Language: English  • 中文 name continent Afghanistan Asia Albania Europe Algeria A ...

  7. 前后端分离demo 旅馆管理系统

    模型设计   旅馆管理系统,主要涉及到登记入住,退房以及客房和客人信息管理:经过分析抽像出涉及到的实体以及各实体之间的关系:   可以看出整个业务以客房为中心,入住,退房,定价,收费都是以客房为基本单 ...

  8. linux 空间释放,mysql数据库空间释放

    测试告急,服务器不行了.down了…… 1.linux如何查看磁盘剩余空间: [root@XXX~]# df -lhFilesystem        Size      Used      Avai ...

  9. &lbrack;Java&rsqb; 用 Comparator 实现排序

    最近正好用到Comparator,发现能对不同类型的对象进行排序(当然排序依据还是基本类型),也不用自己实现排序算法,用起来很方便,所以简单记录一下. 本文地址:http://www.cnblogs. ...

  10. python之socket运用2

    今天实现在客户端和服务端之间进行持续的通信 客户端代码 import socket ip_port = ("127.0.0.1",3000) sk = socket.socket( ...