1 条题解

  • 0
    @ 2026-6-19 10:31:07

    📝 题目大意

    给定 L,RL, R,求满足 LA,B,CRL \leq A, B, C \leq RAB=CA - B = C 的整数三元组 (A,B,C)(A, B, C) 的个数。共 TT 组询问。

    💡 解题思路

    1. 题目分析CCA,BA, B 唯一确定(C=ABC = A - B),因此问题转化为求满足 LA,BRL \leq A, B \leq RLABRL \leq A - B \leq R 的二元组 (A,B)(A, B) 数量。数据范围 R106R \leq 10^6T2×104T \leq 2 \times 10^4,每组询问需要 O(1)O(1) 回答。

    2. 算法推导

      • AB=CA - B = CC[L,R]C \in [L, R],得约束 LABRL \leq A - B \leq R
      • 等价于 B+LAB+RB + L \leq A \leq B + R
      • 结合 A[L,R]A \in [L, R],固定 BBAA 的取值范围为 [max(L,B+L), min(R,B+R)][\max(L, B+L),\ \min(R, B+R)]
      • 由于 BLB \geq L,有 B+L2LLB+L \geq 2L \geq LL0L \geq 0),故 max(L,B+L)=B+L\max(L, B+L) = B+L
      • 由于 BRB \leq R,有 B+RRB+R \geq R,故 min(R,B+R)=R\min(R, B+R) = R
      • 因此固定 BB 时,A[B+L, R]A \in [B+L,\ R],合法 AA 的个数为 max(0, R(B+L)+1)=max(0, RBL+1)\max(0,\ R - (B+L) + 1) = \max(0,\ R - B - L + 1)
      • 要求区间非空即 B+LRB+L \leq R,也就是 BRLB \leq R - L。同时 BLB \geq L,所以 BB 的取值范围为 [L, RL][L,\ R-L]
      • 该区间非空的条件是 LRLL \leq R - L,即 2LR2L \leq R。若 2L>R2L > R,答案为 00(不存在满足条件的 CC,因为 ABA-B 最大为 RLR-L,而 CC 至少为 LL,需要 RLLR-L \geq L)。
      • 2LR2L \leq R 时,令 k=R2L+1k = R - 2L + 1。枚举 BBLLRLR-L,令 i=BLi = B - Lii00R2LR-2L),此时合法 AA 个数为 R(L+i)L+1=kiR - (L+i) - L + 1 = k - i
      • 求和得:$$\sum_{i=0}^{R-2L} (k - i) = k + (k-1) + \cdots + 1 = \frac{k(k+1)}{2}$$
      • 代入 k=R2L+1k = R - 2L + 1,得最终公式:ans=(R2L+1)(R2L+2)2\text{ans} = \frac{(R - 2L + 1)(R - 2L + 2)}{2}
    3. 边界与细节

      • L=0L = 0 的情况:公式仍然适用。例如 L=0,R=0L=0, R=02L=0R2L=0 \leq Rk=00+1=1k = 0-0+1 = 1ans=1×2/2=1\text{ans}=1 \times 2 / 2 = 1,对应 (0,0,0)(0,0,0)
      • 2L=R2L = R 的情况k=2L2L+1=1k = 2L - 2L + 1 = 1ans=1\text{ans}=1,仅有一种情况(A=R,B=L,C=LA=R, B=L, C=L)。
      • 2L>R2L > R 的情况if 条件不成立,ans 保持为 00,直接输出。
      • 溢出R106R \leq 10^6k106+1k \leq 10^6+1k(k+1)/25×1011k(k+1)/2 \approx 5 \times 10^{11},在 long long 范围内,但需注意使用 long long 类型。

    ⏱️ 复杂度分析

    • 时间复杂度:每组数据 O(1)O(1) 计算,总复杂度 O(T)O(T)
    • 空间复杂度:仅使用常数个变量,O(1)O(1)

    💻 标准代码 (C++)

    #include <bits/stdc++.h>
    using namespace std;
    #define ll long long
    int main() {
        int tt;
        cin >> tt;
        while(tt--){
            ll l, r;
            cin >> l >> r;
            ll ans = 0;
            // 当 2L <= R 时才有解,否则 ans = 0
            if(r >= 2 * l)
                // k = R - 2L + 1, ans = k * (k + 1) / 2
                ans = (r - 2 * l + 1) * (r - 2 * l + 2) / 2;
            cout << ans << '\n';
        }
        return 0;
    }
    
    • 1

    信息

    ID
    860
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    (无)
    递交数
    1
    已通过
    1
    上传者