下面系统整理向上取整 ceil / 向下取整 floor 的常见运算性质,并结合本题中出现的
\[\left\lfloor \frac{len}{2} \right\rfloor
\]
说明为什么会有
\[4\left\lfloor \frac{len}{2} \right\rfloor = 2(len-1)
\]
这种化简。
一、定义
1. 向下取整 floor
\[\lfloor x \rfloor
\]
表示不超过 \(x\) 的最大整数。
例如:
\[\lfloor 3.7 \rfloor = 3
\]
\[\lfloor 5 \rfloor = 5
\]
\[\lfloor -1.2 \rfloor = -2
\]
注意:负数向下取整是往更小的方向走。
2. 向上取整 ceil
\[\lceil x \rceil
\]
表示不小于 \(x\) 的最小整数。
例如:
\[\lceil 3.2 \rceil = 4
\]
\[\lceil 5 \rceil = 5
\]
\[\lceil -1.2 \rceil = -1
\]
二、基本性质
1. 整数不变性
如果 \(x\) 本身是整数,那么:
\[\lfloor x \rfloor = x
\]
\[\lceil x \rceil = x
\]
2. 夹逼性质
对任意实数 \(x\):
\[\lfloor x \rfloor \le x < \lfloor x \rfloor + 1
\]
也就是说:
\[x = \lfloor x \rfloor + \{x\}
\]
其中:
\[0 \le \{x\} < 1
\]
\(\{x\}\) 是 \(x\) 的小数部分。
类似地:
\[\lceil x \rceil - 1 < x \le \lceil x \rceil
\]
3. floor 与 ceil 的关系
有恒等式:
\[\lceil x \rceil = -\lfloor -x \rfloor
\]
以及:
\[\lfloor x \rfloor = -\lceil -x \rceil
\]
例子:
\[\lceil 2.3 \rceil = 3
\]
\[-\lfloor -2.3 \rfloor = -(-3) = 3
\]
三、加减整数的性质
如果 \(n\) 是整数,那么:
\[\lfloor x+n \rfloor = \lfloor x \rfloor + n
\]
\[\lceil x+n \rceil = \lceil x \rceil + n
\]
例子:
\[\lfloor 3.4 + 2 \rfloor = \lfloor 5.4 \rfloor = 5
\]
而:
\[\lfloor 3.4 \rfloor + 2 = 3+2 = 5
\]
这个性质非常常用。
四、单调性
如果:
\[x \le y
\]
那么:
\[\lfloor x \rfloor \le \lfloor y \rfloor
\]
\[\lceil x \rceil \le \lceil y \rceil
\]
也就是说,floor 和 ceil 都是单调不减函数。
五、加法性质
1. floor 的加法
\[\lfloor x \rfloor + \lfloor y \rfloor \le \lfloor x+y \rfloor \le \lfloor x \rfloor + \lfloor y \rfloor + 1
\]
也就是说,两个数分别向下取整后再相加,可能会比先相加再向下取整少 0 或 1。
例子:
\(x=1.4,\quad y=2.3\)
\[\lfloor x \rfloor + \lfloor y \rfloor = 1+2=3
\]
\[\lfloor x+y \rfloor = \lfloor 3.7 \rfloor = 3
\]
相等。
但如果:
\(x=1.6,\quad y=2.7\)
\[\lfloor x \rfloor + \lfloor y \rfloor = 1+2=3
\]
\[\lfloor x+y \rfloor = \lfloor 4.3 \rfloor = 4
\]
多了 1。
2. ceil 的加法
\[\lceil x \rceil + \lceil y \rceil - 1 \le \lceil x+y \rceil \le \lceil x \rceil + \lceil y \rceil
\]
例子:
\(x=1.2,\quad y=2.3\)
\[\lceil x \rceil + \lceil y \rceil = 2+3=5
\]
\[\lceil x+y \rceil = \lceil 3.5 \rceil = 4
\]
少了 1。
六、除以正整数的复合性质
如果 \(m\) 是正整数,那么:
\[\left\lfloor \frac{\lfloor x \rfloor}{m} \right\rfloor = \left\lfloor \frac{x}{m} \right\rfloor
\]
类似地:
\[\left\lceil \frac{\lceil x \rceil}{m} \right\rceil = \left\lceil \frac{x}{m} \right\rceil
\]
这个在整数除法、分块、数论中经常用。
七、整数除法中的 floor / ceil
在算法竞赛中,最常见的是对整数做除法。
设 \(a\) 是整数,\(b\) 是正整数。
1. 向下取整除法
\[\left\lfloor \frac{a}{b} \right\rfloor
\]
如果 \(a \ge 0\),那么 C++ 中的:
a / b
就是:
\[\left\lfloor \frac{a}{b} \right\rfloor
\]
例如:
7 / 2 = 3
对应:
\[\left\lfloor \frac{7}{2} \right\rfloor = 3
\]
2. 向上取整除法
如果 \(a \ge 0\),\(b > 0\),那么:
\[\left\lceil \frac{a}{b} \right\rceil = \left\lfloor \frac{a+b-1}{b} \right\rfloor
\]
在 C++ 中可以写成:
(a + b - 1) / b
例如:
\[\left\lceil \frac{7}{2} \right\rceil = 4
\]
代码:
(7 + 2 - 1) / 2 = 8 / 2 = 4
再例如:
\[\left\lceil \frac{8}{3} \right\rceil = 3
\]
代码:
(8 + 3 - 1) / 3 = 10 / 3 = 3
3. 更安全的写法
为了避免 a + b - 1 溢出,也可以写成:
a / b + (a % b != 0)
即:
a / b + (a % b ? 1 : 0)
这个只适用于 \(a \ge 0\)。
八、与模运算的关系
设 \(a\) 是整数,\(b\) 是正整数。
若:
\[r = a \bmod b
\]
并且规定:
\[0 \le r < b
\]
那么:
\[a = b \left\lfloor \frac{a}{b} \right\rfloor + r
\]
所以:
\[\left\lfloor \frac{a}{b} \right\rfloor = \frac{a-r}{b}
\]
例如:
\[7 = 2 \cdot 3 + 1
\]
所以:
\[\left\lfloor \frac{7}{2} \right\rfloor = 3
\]
九、和 2 有关的性质
本题中主要用到的是除以 2 的向下取整。
设 \(n\) 是整数。
1. 若 \(n\) 是偶数
设:
\[n = 2k
\]
那么:
\[\left\lfloor \frac{n}{2} \right\rfloor = k
\]
\[\left\lceil \frac{n}{2} \right\rceil = k
\]
例如:
\(n=6\)
\[\left\lfloor \frac{6}{2} \right\rfloor = 3
\]
\[\left\lceil \frac{6}{2} \right\rceil = 3
\]
2. 若 \(n\) 是奇数
设:
\[n = 2k+1
\]
那么:
\[\left\lfloor \frac{n}{2} \right\rfloor = k
\]
\[\left\lceil \frac{n}{2} \right\rceil = k+1
\]
也可以写成:
\[\left\lfloor \frac{n}{2} \right\rfloor = \frac{n-1}{2}
\]
\[\left\lceil \frac{n}{2} \right\rceil = \frac{n+1}{2}
\]
例如:
\(n=5\)
\[\left\lfloor \frac{5}{2} \right\rfloor = 2
\]
\[\left\lceil \frac{5}{2} \right\rceil = 3
\]
并且:
\[\frac{5-1}{2}=2
\]
\[\frac{5+1}{2}=3
\]
3. floor 与 ceil 的和
对任意整数 \(n\):
\[\left\lfloor \frac{n}{2} \right\rfloor + \left\lceil \frac{n}{2} \right\rceil = n
\]
例子:
\(n=5\)
\[2+3=5
\]
\(n=6\)
\[3+3=6
\]
4. 常见等价式
对于整数 \(n\):
\[\left\lfloor \frac{n}{2} \right\rfloor = \left\lceil \frac{n-1}{2} \right\rceil
\]
\[\left\lceil \frac{n}{2} \right\rceil = \left\lfloor \frac{n+1}{2} \right\rfloor
\]
这些在写代码时很有用。
十、本题中的关键性质
本题中有:
\[\left\lfloor \frac{len}{2} \right\rfloor
\]
当 len 为奇数时,设:
\[len = 2k+1
\]
那么:
\[\left\lfloor \frac{len}{2} \right\rfloor = k
\]
而:
\[\frac{len-1}{2} = \frac{2k}{2} = k
\]
所以:
\[\left\lfloor \frac{len}{2} \right\rfloor = \frac{len-1}{2}
\]
于是:
\[4\left\lfloor \frac{len}{2} \right\rfloor = 4\cdot \frac{len-1}{2}
\]
因为 \(len-1\) 是偶数,所以可以直接约分:
\[4\cdot \frac{len-1}{2} = 2(len-1)
\]
因此:
\[4\left\lfloor \frac{len}{2} \right\rfloor = 2(len-1)
\]
这就是题解中:
\[P \equiv sum + 4\cdot \frac{len-1}{2} \equiv sum + 2(len-1) \pmod 8
\]
的来源。
十一、用例子验证
例 1:len = 3
\[\left\lfloor \frac{3}{2} \right\rfloor = 1
\]
\[4\left\lfloor \frac{3}{2} \right\rfloor = 4
\]
而:
\[2(3-1)=4
\]
相等。
例 2:len = 5
\[\left\lfloor \frac{5}{2} \right\rfloor = 2
\]
\[4\left\lfloor \frac{5}{2} \right\rfloor = 8
\]
而:
\[2(5-1)=8
\]
相等。
例 3:len = 7
\[\left\lfloor \frac{7}{2} \right\rfloor = 3
\]
\[4\left\lfloor \frac{7}{2} \right\rfloor = 12
\]
而:
\[2(7-1)=12
\]
相等。
十二、向上取整与向下取整的奇偶性
本题还隐含了一个点:偶数轮的数量是:
\[\left\lfloor \frac{len}{2} \right\rfloor
\]
奇数轮的数量是:
\[\left\lceil \frac{len}{2} \right\rceil
\]
因为第 1 轮是奇数轮,第 2 轮是偶数轮,第 3 轮是奇数轮……
所以:
len |
奇数轮数 |
偶数轮数 |
| 1 |
1 |
0 |
| 2 |
1 |
1 |
| 3 |
2 |
1 |
| 4 |
2 |
2 |
| 5 |
3 |
2 |
| 6 |
3 |
3 |
公式就是:
\[\text{奇数轮数} = \left\lceil \frac{len}{2} \right\rceil
\]
\[\text{偶数轮数} = \left\lfloor \frac{len}{2} \right\rfloor
\]
十三、与模 4 的关系
有时还需要判断:
\[\left\lfloor \frac{n}{2} \right\rfloor
\]
的奇偶性。
设:
\[n \bmod 4
\]
则有:
| \(n \bmod 4\) |
\(\left\lfloor \frac{n}{2} \right\rfloor \bmod 2\) |
| 0 |
0 |
| 1 |
0 |
| 2 |
1 |
| 3 |
1 |
也就是说:
\[\left\lfloor \frac{n}{2} \right\rfloor \bmod 2 = \begin{cases} 0, & n \equiv 0,1 \pmod 4 \\ 1, & n \equiv 2,3 \pmod 4 \end{cases}
\]
例子:
\(n=5\)
\[\left\lfloor \frac{5}{2} \right\rfloor = 2
\]
2 是偶数。
\[5 \bmod 4 = 1
\]
对应结果为 0。
十四、C++ 中的注意事项
在 C++ 中,整数除法是向零取整。
对于正数,向零取整和向下取整一样。
例如:
7 / 2; // 3
等同于:
\[\left\lfloor \frac{7}{2} \right\rfloor
\]
但对于负数不一样。
例如:
-3 / 2; // -1
但数学上的向下取整是:
\[\left\lfloor \frac{-3}{2} \right\rfloor = -2
\]
所以如果涉及负数除法,要特别小心。
1. 正整数的向上取整
如果 a >= 0,b > 0:
int ceil_div(int a, int b) {
return (a + b - 1) / b;
}
或者更安全:
int ceil_div(int a, int b) {
return a / b + (a % b != 0);
}
2. 可能为负数的向下取整
如果 a 可能为负数,b > 0,可以这样写:
int floor_div(int a, int b) {
int q = a / b;
int r = a % b;
if (r < 0) --q;
return q;
}
3. 可能为负数的向上取整
int ceil_div(int a, int b) {
int q = a / b;
int r = a % b;
if (r > 0) ++q;
return q;
}
十五、总结
最常用的是下面这些:
1. 对正整数除法
\[\left\lfloor \frac{a}{b} \right\rfloor = a / b
\]
\[\left\lceil \frac{a}{b} \right\rceil = \frac{a+b-1}{b}
\]
代码:
a / b
(a + b - 1) / b
2. 对 2 的特殊情况
若 \(n = 2k\):
\[\left\lfloor \frac{n}{2} \right\rfloor = \left\lceil \frac{n}{2} \right\rceil = k
\]
若 \(n = 2k+1\):
\[\left\lfloor \frac{n}{2} \right\rfloor = k
\]
\[\left\lceil \frac{n}{2} \right\rceil = k+1
\]
3. 本题中的核心
若 len 为奇数:
\[\left\lfloor \frac{len}{2} \right\rfloor = \frac{len-1}{2}
\]
所以:
\[4\left\lfloor \frac{len}{2} \right\rfloor = 4\cdot \frac{len-1}{2} = 2(len-1)
\]
因此可以定义:
\[H = sum + 2(len-1) \pmod 8
\]
并用:
\[H = 3
\]
判断全奇路径是否为良列。