题解:P11495 [ROIR 2019 Day 1] 两次测量

· · 题解

这道题题意是在区间区间 [l, r]中,有多少个对 (i, j)满足j-ia的倍数。这道题要是枚举只能30分,想得满分只能O(1)时间复杂度,只能推公式。

$(t - t \bmod a) \div a$ 计算的是从 $l$ 到 $r$ 时间段中完整的 a 个小时的数量。例如,假设 $t = 10,a = 3$,那么 $(t - t \bmod a) \div a = (10 - 1) \div 3 = 3$,意味着在这个时间段内完整的自转圈数有 3 个。 $t \div a - 1$ 计算的是从$ l $到$ r $时间段内的测量间隔数$($即跳过步长为$ a $的可能测量对数$)$如果$ t = 10,a = 3$,那么 $t \div a - 1 = 10 \div 3 - 1 = 2$,表示从$ l $到$ r $的有效测量区间对数。 $t \bmod a$ 计算的是不能构成完整自转周期的剩余时间。例如,如果 $t = 10,a = 3$,那么 $t \bmod a = 1$,即剩余 $1$ 小时没有组成完整的周期。 $t \div a$ 是时间段内完整的周期数。 $(t - t \bmod a) \div a \times (t \div a - 1) \div 2 \times a$ 计算的是从完整周期中可以获得的所有合法的 $(i, j) $对数。 剩余部分的合法对数是 $t \bmod a \times (t \div a)$。 ## $AC code
#include <bits/stdc++.h>
#define endl '\n'
#define int long long
using std::cin;
using std::cout;
using std::vector;
const int MAXN = 1e5 + 10;

void solve();
signed main() {
    std::ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    int _T = 1;
    /*cin >> _T;*/
    while (_T--) {
        solve();
    }

    return 0;
}

void solve(){
    int l, r, a ,t;
    cin>>l>>r>>a;
    t=r-l+1;
    cout<<(t-t%a)/a*(t/a-1)/2*a+t%a*(t/a);

}