1. 问题分析与解法思路
这道题目要求我们计算给定区间[l,r]内所有2的倍数的个数。作为一个基础数论问题,它考察的是对整数性质和简单数学运算的理解。我们先来看最直观的解法思路。
最直接的方法就是遍历区间内的每个数字,判断是否能被2整除。这种方法虽然简单,但时间复杂度是O(n),当区间范围很大时效率不高。实际上,这个问题可以通过数学方法在O(1)时间内解决。
1.1 数学规律分析
观察2的倍数在整数序列中的分布规律:它们是每隔一个数出现一次。也就是说,在连续的整数序列中,2的倍数出现的频率是固定的。
具体来说:
- 在1到n的范围内,2的倍数的个数是⌊n/2⌋
- 在l到r的范围内,2的倍数的个数可以表示为⌊r/2⌋ - ⌊(l-1)/2⌋
这个公式的原理是:计算从1到r的2的倍数个数,减去从1到(l-1)的2的倍数个数,就得到区间[l,r]内的2的倍数个数。
1.2 边界情况处理
在实际编码中,我们需要特别注意区间的边界情况。题目中给出的解法实际上是通过判断l和r的奇偶性来简化计算:
- 当l和r都是奇数时:区间内2的倍数个数为(r-l)/2
- 当l和r中至少有一个是偶数时:区间内2的倍数个数为(r-l)/2 + 1
这个方法的正确性可以通过具体例子验证。例如:
- 区间[3,7](两个奇数):3,4,5,6,7 → 4,6是2的倍数 → (7-3)/2=2个
- 区间[2,6](一个偶数一个偶数):2,3,4,5,6 → 2,4,6是2的倍数 → (6-2)/2+1=3个
- 区间[3,6](一个奇数一个偶数):3,4,5,6 → 4,6是2的倍数 → (6-3)/2+1=2个
2. 代码实现与解析
2.1 完整代码展示
cpp复制#include <iostream>
using namespace std;
int main() {
int l, r;
cin >> l >> r;
if (l % 2 == 1 && r % 2 == 1) {
cout << (r - l) / 2;
} else {
cout << (r - l) / 2 + 1;
}
return 0;
}
