[HAOI 2011]Problem b
Description
Input
第一行一个整数n,接下来n行每行五个整数,分别表示a、b、c、d、k
Output
共n行,每行一个整数表示满足要求的数对(x,y)的个数
Sample Input
2 5 1 5 1
1 5 1 5 2
Sample Output
3
HINT
100%的数据满足:1≤n≤50000,1≤a≤b≤50000,1≤c≤d≤50000,1≤k≤50000
题解
记 $f(x, y)$ 为满足 $gcd(i,j)=k$ 的数对 $(i,j)~~(i\in[1,x],j\in[1,y])$ 的个数。
由容斥原理,答案就是 $ans=f(b,d)-f((a-1),d)-f(b,(c-1))+f((a-1),(c-1))$ 。
我们现在考虑如何求 $f(x,y)$ 。
我们按照以往的套路,将 $k$ 提出,显然 $$f(a,b)=\sum_{i=1}^{\left\lfloor\frac{a}{k} \right\rfloor}\sum_{j=1}^{\left\lfloor\frac{b}{k} \right\rfloor}[gcd(i,j)=1]$$
由公式 $\sum_{d\mid n} \mu(d)=[n=1]$ ,我们得到
$$\Rightarrow \sum_{i=1}^{\left\lfloor\frac{a}{k} \right\rfloor}\sum_{j=1}^{\left\lfloor\frac{b}{k} \right\rfloor}\sum_{d\mid gcd(i,j)}\mu(d)$$
我们将 $\mu$ 提前
\begin{aligned} &\Rightarrow\sum_{d=1}^{min\left\{\left\lfloor\frac{a}{k} \right\rfloor,\left\lfloor\frac{b}{k} \right\rfloor\right\}}\mu(d)\sum_{i=1,d\mid i}^{\left\lfloor\frac{a}{k} \right\rfloor}\sum_{j=1,d\mid j}^{\left\lfloor\frac{b}{k}\right\rfloor}1\\&\Rightarrow\sum_{d=1}^{min\left\{\left\lfloor\frac{a}{k} \right\rfloor,\left\lfloor\frac{b}{k} \right\rfloor\right\}}\mu(d)\cdot\left\lfloor\frac{\left\lfloor\frac{a}{k}\right\rfloor}{d}\right\rfloor\cdot\left\lfloor\frac{\left\lfloor\frac{b}{k}\right\rfloor}{d}\right\rfloor\end{aligned}
得到这个式子还有第二个方Fa♂,这里也提一下。
令 $F(d)$ 为 $d\mid gcd(i,j)$ 的数对 $(i,j)$ 个数, $f(d)$ 为 $d=gcd(i,j)$ 的数对 $(i,j)$ 个数。
由题 $$F(k)=\sum_{d=1}^{min\left\{\left\lfloor\frac{a}{k}\right\rfloor,\left\lfloor\frac{b}{k} \right\rfloor\right\}}f(kd)$$
由莫比乌斯反演定理 $F(n)=\sum_{n\mid d} f(d)\Rightarrow f(n)=\sum_{n\mid d} \mu(\frac{d}{n})F(d)$
\begin{aligned}\Rightarrow f(k)&=\sum_{d=1}^{min\left\{\left\lfloor\frac{a}{k}\right\rfloor,\left\lfloor\frac{b}{k}\right\rfloor\right\}}\mu(d)F(kd)\\&=\sum_{d=1}^{min\left\{\left\lfloor\frac{a}{k} \right\rfloor,\left\lfloor\frac{b}{k}\right\rfloor\right\}}\mu(d)\cdot\left\lfloor\frac{a}{kd}\right\rfloor\cdot\left\lfloor\frac{b}{kd}\right\rfloor\end{aligned}
那么我们现在只需要 $O(n)$ 的枚举 $d$ 就可以了,但对于多组询问,这个复杂度还是吃不消的。
我们考虑在计算的时候 $\left\lfloor\frac{\left\lfloor\frac{n}{k}\right\rfloor}{d}\right\rfloor$ 是一个分段的,有较长的一段区间内的数是相等的。可以证明这段区间的长度是 $\sqrt{n}$ 的。
证明:
1.当 $1\leq d < \sqrt n$ 时, $d$ 就只有 $\sqrt n$ 个, $\left\lfloor{n \over d}\right\rfloor$ 最多有 $\sqrt n$ 个。
2.当 $\sqrt n \leq d \leq n$ 时,由于 $\left\lfloor{n \over d}\right\rfloor$ 小于 $\sqrt n$ ,所以 $\left\lfloor{n \over d}\right\rfloor$ 最多有 $\sqrt n$ 个。
证毕。
显然对于一段区间内 $\left\lfloor\frac{\left\lfloor\frac{a}{k}\right\rfloor}{d}\right\rfloor$ 和 $\left\lfloor\frac{\left\lfloor\frac{b}{k}\right\rfloor}{d}\right\rfloor$ 相同的数我们可以直接处理 $\mu$ 的前缀,直接求即可。而相同值的区间的右端点为 $\left\lfloor \frac{n}{\left\lfloor\frac{n}{d} \right\rfloor} \right\rfloor$ 。
证明:
对于 $n$ 来说,找到最大的 $j$ 满足 $$\left\lfloor\frac{n}{i}\right\rfloor \leq\left\lfloor\frac{n}{j}\right\rfloor$$
化简一下得到 $$j\leq \left\lfloor\frac{n}{\left\lfloor\frac{n}{i}\right\rfloor}\right\rfloor$$
那么在计算时在分别关于 $a, b$ 的表达式中取一个较小值即可。时间复杂度 $O(n\sqrt n)$ 。
//It is made by Awson on 2018.1.19
#include <set>
#include <map>
#include <cmath>
#include <ctime>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define LL long long
#define Abs(a) ((a) < 0 ? (-(a)) : (a))
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))
#define writeln(x) (write(x), putchar('\n'))
using namespace std;
const int N = ;
const int INF = ~0u>>;
void read(int &x) {
char ch; bool flag = ;
for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || ); ch = getchar());
for (x = ; isdigit(ch); x = (x<<)+(x<<)+ch-, ch = getchar());
x *= -*flag;
}
void write(LL x) {
if (x > ) write(x/);
putchar(x%+);
} LL mu[N+]; int a, b, c, d, k;
void get_mu() {
int isprime[N+], prime[N+], tot = ;
memset(isprime, , sizeof(isprime)); isprime[] = , mu[] = ;
for (int i = ; i <= N; i++) {
if (isprime[i]) mu[i] = -, prime[++tot] = i;
for (int j = ; j <= tot && i*prime[j] <= N; j++)
if (!(i%prime[j])) {isprime[i*prime[j]] = , mu[i*prime[j]] = ; break; }
else isprime[i*prime[j]] = , mu[i*prime[j]] = -mu[i];
mu[i] += mu[i-];
}
}
LL cal(int x, int y) {
if (x > y) Swap(x, y); LL ans = ;
for (int i = , last; i <= x; i = last+) {
last = Min(x/(x/i), y/(y/i));
ans += (LL)(mu[last]-mu[i-])*(x/i)*(y/i);
}
return ans;
}
void work() {
read(a), read(b), read(c), read(d), read(k);
writeln(cal(b/k, d/k)-cal(b/k, (c-)/k)-cal((a-)/k, d/k)+cal((a-)/k, (c-)/k));
}
int main() {
int t; read(t); get_mu();
while (t--) work();
return ;
}
[HAOI 2011]Problem b的更多相关文章
- [BZOJ 2301] [HAOI 2011] Problem b (莫比乌斯反演)(有证明)
[BZOJ 2301] [HAOI 2011] Problem b (莫比乌斯反演)(有证明) 题面 T组询问,每次给出a,b,c,d,k,求\(\sum _{i=a}^b\sum _{j=c}^d[ ...
- [HAOI 2011] Problem A
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=2298 [算法] 考虑用总人数 - 最多人说真话 显然 , 对于每个人 , 如果他说的 ...
- [HAOI 2011]Problem c
Description 给n个人安排座位,先给每个人一个1~n的编号,设第i个人的编号为ai(不同人的编号可以相同),接着从第一个人开始,大家依次入座,第i个人来了以后尝试坐到ai,如果ai被占据了, ...
- [BZOJ 2299][HAOI 2011]向量 题解(裴蜀定理)
[BZOJ 2299][HAOI 2011]向量 Description 给你一对数a,b,你可以任意使用(a,b), (a,-b), (-a,b), (-a,-b), (b,a), (b,-a), ...
- 【BZOJ 2301】【HAOI 2011】Problem b
今天才知道莫比乌斯反演还可以这样:$$F(n)=\sum_{n|d}f(d) \Rightarrow f(n)=\sum_{n|d}\mu(\frac{d}{n})F(d)$$我好弱,,,对于$$F( ...
- 数学(莫比乌斯反演):HAOI 2011 问题B
题目描述: 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函数为x和y的最大公约数. 输入格式: 第一行一个整数n,接下来n ...
- [HAOI 2011]向量
Description 题库链接 给你一对数 \(a,b\) ,你可以任意使用 \((a,b), (a,-b), (-a,b), (-a,-b), (b,a), (b,-a), (-b,a), (-b ...
- HDU 2011 多项式求和
http://acm.hdu.edu.cn/showproblem.php?pid=2011 Problem Description 多项式的描述如下:1 - 1/2 + 1/3 - 1/4 + 1/ ...
- Warsaw U Contest Petrozavo dsk Summer 2011 Training Camp, Monday, September 5, 2011
Warsaw U Contest Petrozavo dsk Summer 2011 Training Camp, Monday, September 5, 2011 Problem A.Chocol ...
随机推荐
- 关于Netty的入门使用
Netty介绍: Netty是一个提供异步事件驱动的网络应用框架,用以快速开发高性能.高可靠性的网络服务器和客户端程序. 换句话说,Netty是一个NIO框架,使用它可以简单快速地开发网络应用程序,比 ...
- Java基础学习笔记二十五 MySQL
MySQL 在dos中操作mysql 连接mysql命令: mysql -uroot -p密码 ,连接OK,会出现mysql> 对数据库的操作 创建一个库 create database 库名 ...
- Leetcode 4——Partition List
Problems: Given a linked list and a value x, partition it such that all nodes less than x come befor ...
- C语言--第六周作业
一.高速公路超速罚款 1.代码 #include<stdio.h> int main() { int a,b; float c; scanf("%d %d",& ...
- 201621123031 《Java程序设计》第10周学习总结
作业10-异常 1.本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 1.捕捉异常 Java中的异常捕获结构由try.catch和finally三个部分组成.其中try语句 ...
- vue jquery js 获取当前时间本周的第一天 和 本月的第一天
交互的时候传输数据 后台要求这样的数据 直接上代码 这是我找度姨要的 附上链接 https://www.cnblogs.com/wasabii/p/7756560.html 它里面有本季度第一天 ...
- vue下拉列表
最近在弄作品,做了个下拉列表.心想各位小哥哥.小姐姐可能会用到相同的需求,就把下拉列表封装一下,希望能对各位小哥哥,小姐姐有帮助 github地址:https://github.com/ClmPisc ...
- 【第二十篇】C#微信H5支付 非微信内浏览器H5支付 浏览器微信支付
微信开发者文档 微信H5支付官方文档 请阅读清楚 最起码把所有参数看一遍 这个地方也可以看看 微信案例 http://wxpay.wxutil.com/mch/pay/h5.v2.php,请在微 ...
- python3全栈开发-面向对象、面向过程
一. 什么是面向对象的程序设计及为什么要有它 1.面向过程 面向过程的程序设计:核心是过程二字,过程指的是解决问题的步骤,即先干什么再干什么......面向过程的设计就好比精心设计好一条流水线,是一种 ...
- 真正理解拉格朗日乘子法和 KKT 条件
这篇博文中直观上讲解了拉格朗日乘子法和 KKT 条件,对偶问题等内容. 首先从无约束的优化问题讲起,一般就是要使一个表达式取到最小值: \[min \quad f(x)\] 如 ...