【HYSBZ 2301】——莫比乌斯反演
2016-05-11 21:21
267 查看
Time Limit: 50 Sec Memory Limit: 256 MB
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
第一次写莫比乌斯反演的题,WA了好几次,竟然是爆int了,QAQ.
那么什么是莫比乌斯反演呢?
定理:f(n)f(n)和g(n)g(n)是定义在非负整数集合上的两个函数,并且满足g(n)=∑d|nf(d)g(n) =\sum\limits_{d|n}f(d) 条件,那么我们得到结论f(n)=∑d|nμ(d)g(nd)=∑n|dμ(dn)g(d)f(n) = \sum\limits_{d|n}\mu(d)g(\frac{n}{d}) = \sum\limits_{n|d}\mu(\frac{d}{n})g(d),在这个公式中有一个μ(d)\mu(d)函数,它的定义如下
1. 若 d = 1,那么 μ(d)=1\mu(d) = 1
2. 若d=p1p2⋯pk均为互异的素数d = p_1p_2\cdots p_k均为互异的素数,那么μ(d)=(−1)k\mu(d) = (-1)^{k}
3. 其他情况为0.
它有如下的性质:
1. 对于任意正整数n有 ∑d|nμ(d)=[n=1]\sum\limits_{d|n}\mu(d) = [n=1]
2. ∑d|nμ(d)d=φ(n)n\sum\limits_{d|n}\frac{\mu(d)}{d} = \frac{\varphi(n)}{n}
在这个题中,我们定义f(n)表示gcd(x,y) =n的数量,g(n)表示n|gcd(x,y)的数量,
所以f(n)=∑n|dμ(dn)g(d)f(n) = \sum\limits_{n|d}\mu(\frac{d}{n})g(d)由于n=1,所以f(1)=∑dμ(d)g(d)=∑dμ(d)[nd][md]f(1) = \sum\limits_{d}\mu(d)g(d) = \sum\limits_{d} \mu(d)[\frac{n}{d}][\frac{m}{d}]。
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
第一次写莫比乌斯反演的题,WA了好几次,竟然是爆int了,QAQ.
那么什么是莫比乌斯反演呢?
定理:f(n)f(n)和g(n)g(n)是定义在非负整数集合上的两个函数,并且满足g(n)=∑d|nf(d)g(n) =\sum\limits_{d|n}f(d) 条件,那么我们得到结论f(n)=∑d|nμ(d)g(nd)=∑n|dμ(dn)g(d)f(n) = \sum\limits_{d|n}\mu(d)g(\frac{n}{d}) = \sum\limits_{n|d}\mu(\frac{d}{n})g(d),在这个公式中有一个μ(d)\mu(d)函数,它的定义如下
1. 若 d = 1,那么 μ(d)=1\mu(d) = 1
2. 若d=p1p2⋯pk均为互异的素数d = p_1p_2\cdots p_k均为互异的素数,那么μ(d)=(−1)k\mu(d) = (-1)^{k}
3. 其他情况为0.
它有如下的性质:
1. 对于任意正整数n有 ∑d|nμ(d)=[n=1]\sum\limits_{d|n}\mu(d) = [n=1]
2. ∑d|nμ(d)d=φ(n)n\sum\limits_{d|n}\frac{\mu(d)}{d} = \frac{\varphi(n)}{n}
在这个题中,我们定义f(n)表示gcd(x,y) =n的数量,g(n)表示n|gcd(x,y)的数量,
所以f(n)=∑n|dμ(dn)g(d)f(n) = \sum\limits_{n|d}\mu(\frac{d}{n})g(d)由于n=1,所以f(1)=∑dμ(d)g(d)=∑dμ(d)[nd][md]f(1) = \sum\limits_{d}\mu(d)g(d) = \sum\limits_{d} \mu(d)[\frac{n}{d}][\frac{m}{d}]。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <queue> #include <stack> #include <algorithm> using namespace std; typedef long long LL; const int Max = 50100; int mu[Max]; int prime[Max],cnt; bool vis[Max]; int pre[Max]; void GetMu() { memset(vis,false,sizeof(vis)); mu[1] = 1; cnt = 0;pre[1] = 1; for(int i = 2 ; i < Max; i++) { if(!vis[i]) { prime[cnt++] = i; mu[i] = -1; } for(int j = 0;j < cnt && i * prime[j] < Max; j++) { vis[i*prime[j]] = true; if(i%prime[j]) mu[i*prime[j]] = -mu[i]; else { mu[i*prime[j]] = 0; break; } } pre[i] = pre[i-1]+mu[i]; } } LL Cal(LL n,LL m) { int t = min(n,m); LL sum = 0; int end; for(int i = 1;i<= t; i =end+1) { end = min(n/(n/i),m/(m/i)); sum+=((pre[end]-pre[i-1])*(n/i)*(m/i)); } return sum; } int main() { int T; int a,b,c,d,k; GetMu(); scanf("%d",&T); while(T--) { scanf("%d %d %d %d %d",&a,&b,&c,&d,&k); LL sum = Cal(b/k,d/k)-Cal((a-1)/k,d/k)-Cal((c-1)/k,b/k)+Cal((a-1)/k,(c-1)/k); printf("%lld\n",sum); } return 0; }
相关文章推荐
- POJ 2556 Edge 线段的旋转
- Leetcode Everyday: 339. Nested List Weight Sum
- android错误之MediaPlayer用法的Media Player called in state *
- Nignx负载均衡存在的seesion问题
- HDU1068 二分图 最大独立集
- Linux进程
- 随便写写
- 第一章习题
- nyoj 495 少年 DXH
- R语言文本分析(3)
- Project network redundant , Vmware virtualization, Dell VRTX P2V - Part 1 (General Network)
- final关键字
- Linux 异步IO
- 172. Factorial Trailing Zeroes
- 【Python2】range与xrange用法对比
- Java之------socket模拟服务器、浏览器、网络蜘蛛
- java 中的内部类 解释
- OpenGL es 透明问题
- UVA - 11997 K Smallest Sums
- Poj2502 Subway