小欧找数

[题目链接](https://www.nowcoder.com/practice/e821e1ea74a742208a34b4588b2d78e1)

思路

给定两个区间 ,要求有多少个整数 ,使得存在整数 ,满足

转化问题

既然 可以取遍 可以取遍 ,那么 的取值范围就是连续整数区间

,问题变成:当 取遍 中所有整数时, 能产生多少种不同的值?

关键观察

是一个不递减的函数。当 从最小值连续增大到最大值时, 也从最小值连续增大到最大值(每两个连续的 值产生同一个 值)。

因此, 的取值是一段连续的整数区间,答案就是:

$$

举例

以样例 为例:

  • 的范围是
  • 不同的值为 ,共

用公式计算:,一致。

复杂度分析

  • 时间复杂度,只需读入四个数并做一次加法和除法。
  • 空间复杂度

代码

#include <bits/stdc++.h>
using namespace std;
int main() {
    long long l1, r1, l2, r2;
    cin >> l1 >> r1 >> l2 >> r2;
    long long lo = l1 + l2;
    long long hi = r1 + r2;
    auto floorDiv = [](long long a, long long b) -> long long {
        return a / b - (a % b != 0 && (a ^ b) < 0);
    };
    cout << floorDiv(hi, 2) - floorDiv(lo, 2) + 1 << endl;
    return 0;
}
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        long l1 = sc.nextLong(), r1 = sc.nextLong();
        long l2 = sc.nextLong(), r2 = sc.nextLong();
        long lo = l1 + l2;
        long hi = r1 + r2;
        System.out.println(Math.floorDiv(hi, 2) - Math.floorDiv(lo, 2) + 1);
    }
}