1 条题解

  • 0
    @ 2026-4-19 19:33:41

    题目解析

    我们有一个整数 xx1x1061 \le x \le 10^6)和一个很大的整数 mm1m10181 \le m \le 10^{18})。需要统计满足以下条件的 yy1ym1 \le y \le m)的个数:

    1. xyx \ne y
    2. xyx \oplus yxxyy 的除数

    关键观察

    观察 11

    由于 x>0x > 0y>0y > 0xyx \oplus y 不可能等于 xxyy(因为异或运算只有当另一个数为 00 时才可能相等,而 y1y \ge 1)。

    观察 22

    如果 ddpp 的一个除数且 d<pd < p,那么 dp2d \le \lfloor \frac{p}{2} \rfloor
    这意味着除数最多是原数的一半。

    观察 33(核心结论)

    如果 y2xy \ge 2x,那么 xyx \oplus y 不可能成为 xxyy 的除数。

    证明:

    • 首先,当 y2xy \ge 2x 时,yy 的最高二进制位一定高于 xx 的最高二进制位。
      因此,xyx \oplus y 的最高位与 yy 相同,所以 $x \oplus y \ge 2^{\lfloor \log_2 y \rfloor} > \frac{y}{2}$。

    • xyx \oplus yyy 的除数,则必须满足 xyy2x \oplus y \le \frac{y}{2}(因为除数小于 yy 时最多为 y/2y/2)。
      但我们已经得到 xy>y2x \oplus y > \frac{y}{2},矛盾。所以 xyx \oplus y 不能yy 的除数。

    • 同理,xyx \oplus y 的最高位也高于 xx 的最高位,所以 xy>xx \oplus y > x
      xyx \oplus yxx 的除数,则必须满足 xyx2x \oplus y \le \frac{x}{2}(因为除数小于 xx 时最多为 x/2x/2),但这与 xy>xx \oplus y > x 矛盾。
      所以 xyx \oplus y 也不能xx 的除数。

    因此,当 y2xy \ge 2x 时,不存在满足条件的 yy


    结论

    我们只需要考虑 y<2xy < 2x 的范围。
    由于 x106x \le 10^62x2×1062x \le 2 \times 10^6,这是一个可以枚举的范围。


    算法步骤

    对于每个测试用例:

    11. 读入 xxmm22. 令 limit=min(2x,m)limit = \min(2x, m),因为:

    • y2xy \ge 2x 时无解
    • 同时 yy 不能超过 mm 33. 枚举 y=1y = 1limitlimit
    • 如果 x=yx = y,跳过
    • d=xyd = x \oplus y
    • 如果 dd 能整除 xx 或能整除 yy,则计数加 11 44. 输出计数

    时间复杂度

    每个测试用例枚举 O(x)O(x)yy,所有测试用例的 xx 之和不超过 10710^7,因此总复杂度为 O(x)O(\sum x),在时限内可行。


    代码实现

    #include<bits/stdc++.h>
    using namespace std;
    
    using ll = long long;
    
    void solve() {
      int x; ll m; cin >> x >> m;
    
      int ans = 0;
      // 只需要枚举 y < 2x 且 y <= m 的范围
      for (int y = 1; y <= min(2LL * x, m); y++) {
        if (x != y) {
          int d = x ^ y;
          if (x % d == 0 || y % d == 0) {
            ++ans;
          }
        }
      }
      cout << ans << '\n';
    }
    
    int32_t main() {
      ios_base::sync_with_stdio(0);
      cin.tie(0);
      int t = 1;
      cin >> t;
      while (t--) {
        solve();
      }
      return 0;
    }
    

    示例验证

    以第一个测试用例 x=6,m=9x = 6, m = 9 为例:

    • 2x=122x = 12limit=min(12,9)=9limit = \min(12, 9) = 9
    • 枚举 y=1y = 199
    yy xyx \oplus y 是否能整除 xxyy 有效
    11 77
    22 44
    33 55
    44 22 能整除 6644
    55 33 能整除 66
    66 00 跳过(x=yx = y
    77 11 能整除 6677
    88 1414
    99 1515

    结果:33 个有效值(y=4,5,7y = 4, 5, 7),与题目输出一致。

    • 1

    信息

    ID
    6600
    时间
    1000ms
    内存
    256MiB
    难度
    1
    标签
    递交数
    1
    已通过
    1
    上传者