2702. problem b
2022/6/29 6:20:14
本文主要是介绍2702. problem b,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
题目链接
2702. problem b
同215. 破译密码
对于给出的 \(n\) 个询问,每次求有多少个数对 \((x,y)\),满足 \(a≤x≤b,c≤y≤d\),且 \(\text{gcd}(x,y) = k\),\(\text{gcd}(x,y)\) 函数为 \(x\) 和 \(y\) 的最大公约数。
输入格式
第一行一个整数 \(n\)。
接下来 \(n\) 行每行五个整数,分别表示 \(a、b、c、d、k\)。
输出格式
共 \(n\) 行,每行一个整数表示满足要求的数对 \((x,y)\) 的个数。
数据范围
\(1 \le n \le 50000\),
\(1 \le a \le b \le 50000\),
\(1 \le c \le d \le 50000\),
\(1 \le k \le 50000\)
输入样例:
2 2 5 1 5 1 1 5 1 5 2
输出样例:
14 3
解题思路
莫比乌斯反演
本题单用容斥原理和莫比乌斯函数也可做:215. 破译密码
这里介绍莫比乌斯反演做法
先给出莫比乌斯函数的一个性质:\(\sum_{d \mid n} \mu(d)= \begin{cases}1 & n=1 \\ 0 & n \neq 1\end{cases}\) 。简略证明:\(n=1\) 时显然。当 \(n>1\) 时,对 \(n\) 分解质因数:\(n=\prod_{i=1}^{k} p_{i}^{c_{i}}\),当存在 \(c_i>1\) 时该项表示的约数的 \(d\) 的 \(\mu(d)=0\),这种情况的约数不考虑,即只用考虑 \(\prod_{i=1}^{k} p_{i}\) 的约数,即在这 \(k\) 个数中选出 \(1\) 个数组成约数,\(2\) 组成约数,\(3\) 个数组成约数,\(\dots\),组成 \(k\) 个数组成约数,由莫比乌斯函数,奇数种质数为 \(-1\),偶数种质数为 \(1\),则 \(\sum_{d \mid n} \mu(d)=\sum_{i=0}^{k} C_{k}^{i} \cdot(-1)^{i}=(1+(-1))^{k}=0\)
接着,有莫比乌斯反演的两条重要定理:
-
如果有 \(F(n)=\sum_{d \mid n} f(d)\) ,那么有 \(f(n)=\sum_{d \mid n} \mu(d) F\left(\frac{n}{d}\right)\)
证明:将 \(F(n)=\sum_{d \mid n} f(d)\) 代入,得 \(\sum_{d \mid n} \mu(d) \sum_{i\mid \frac{n}{d}}f[i]\),观察 \(i\) 和 \(d\) 配对的情况,当 \(d=1\) 时 \(i\) 取遍 \(n\) 的约数,而对于某个固定的 \(i\),要求找出与 \(i\) 配对的 \(d\),这样的 \(d\) 需满足:\(d\mid n,i\mid \frac{n}{d}\),即 \(d\mid \frac{n}{i}\),此时可以交换 \(i,d\) 顺序,即:\(\sum_{i \mid n} f(i) \sum_{d\mid \frac{n}{i}}\mu(d)\),由莫比乌斯函数约数和性质,当且仅当 \(i=n\) 时后面的和不为 \(0\),即\(\sum_{i \mid n} f(i) \sum_{d\mid \frac{n}{i}}\mu(d)=f(n)\) -
如果有 \(F(n)=\sum_{n \mid d} f(d)\) ,那么有 \(f(n)=\sum_{n \mid d} \mu\left(\frac{d}{n}\right) F(d)\)
同理。这条定理常用。
本题按前缀和可转化为求解:\(\sum_{i=1}^{a} \sum_{j=1}^{b}[(i, j)=n]\),其中 \((i,j)\) 表示 \(i\) 和 \(j\) 的最大公约数
由莫比乌斯反演的性质,求解 \(F(n)\) 容易,求解 \(f(n)\) 困难,本题中 \(f(n)=\sum_{i=1}^{a} \sum_{j=1}^{b}[(i, j)=n]\),而由莫比乌斯反演第二条定理,可设定 \(F(n)=\sum_{i=1}^{a} \sum_{j=1}^{b}[n\mid (i, j)]\),其含义表示的是 \(x\in [1,a],y\in [1,b]\) 中 \(gcd(x,y)\) 是 \(n\) 的倍数的点数,\([1,a]\) 中有 \(a/n\) 个值是 \(n\) 的倍数,\([1,b]\) 中有 \(b/n\) 个值是 \(n\) 的倍数,由乘法原理,共有 \((a/n)\times (b/n)\) 个点满足要求,即 \(F(n)=(a/n)\times (b/n)\),则 $f(n)=\sum_{n \mid d} \mu\left(\frac{d}{n}\right)(a/d)\times (b/d) $,令 \(d'=\frac{d}{n}\),则 $f(n)=\sum_{d'} \mu(d')(a/d'n)\times (b/d'n) $,而倍数 \(d'\) 也不能无限大,$(d')(a/d'n)\times (b/d'n) $ 导致 \(d'\) 最大为 \(n=min(a/n,b/n)\),令 \(a=a/n,b=b/n\),即 $f(n)=\sum_{i=1}^n\mu(i)(a/i)\times (b/i) $,此时转化为单靠容斥原理得到的结论
- 时间复杂度:\((n\sqrt{n})\)
代码
// Problem: problem b // Contest: AcWing // URL: https://www.acwing.com/problem/content/2704/ // Memory Limit: 64 MB // Time Limit: 3000 ms // // Powered by CP Editor (https://cpeditor.org) // %%%Skyqwq #include <bits/stdc++.h> //#define int long long #define help {cin.tie(NULL); cout.tie(NULL);} #define pb push_back #define fi first #define se second #define mkp make_pair using namespace std; typedef long long LL; typedef pair<int, int> PII; typedef pair<LL, LL> PLL; template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; } template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; } template <typename T> void inline read(T &x) { int f = 1; x = 0; char s = getchar(); while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); } while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar(); x *= f; } const int N=5e4+5; int q,a,b,c,d,k,m,prime[N],v[N],u[N],s[N]; void primes(int n) { u[1]=1; for(int i=2;i<=n;i++) { if(v[i]==0) { u[i]=-1; v[i]=prime[++m]=i; } for(int j=1;prime[j]*i<=n&&j<=m;j++) { if(v[i]<prime[j])break; if(i%prime[j]==0) u[i*prime[j]]=0; else u[i*prime[j]]=-u[i]; v[i*prime[j]]=prime[j]; } } for(int i=1;i<=n;i++)s[i]=s[i-1]+u[i]; } int g(int a,int b) { return a/(a/b); } LL f(int a,int b,int d) { LL res=0; a/=d,b/=d; int n=min(a,b); for(int l=1,r;l<=n;l=r+1) { r=min({n,g(a,l),g(b,l)}); res+=1ll*(s[r]-s[l-1])*(a/l)*(b/l); } return res; } int main() { primes(N-1); cin>>q; while(q--) { cin>>a>>b>>c>>d>>k; cout<<f(b,d,k)-f(b,c-1,k)-f(a-1,d,k)+f(a-1,c-1,k)<<'\n'; } return 0; }
这篇关于2702. problem b的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解
- 2024-11-23Java对接阿里云智能语音服务入门教程
- 2024-11-23JAVA对接阿里云智能语音服务入门教程
- 2024-11-23Java副业入门:初学者的简单教程
- 2024-11-23JAVA副业入门:初学者的实战指南