和上一道题的思路类似,把相同的答案合并到一起计算。
官方题解也说了,需要巨大多分讨,将原序列分成若干个连续的求和段即可。
#include<cstdio>
#define int long long
int init(){
char c = getchar();
int x = 0, f = 1;
for (; c < '0' || c > '9'; c = getchar())
if (c == '-') f = -1;
for (; c >= '0' && c <= '9'; c = getchar())
x = (x << 1) + (x << 3) + (c ^ 48);
return x * f;
}
void print(int x){
if (x < 0) x = -x, putchar('-');
if (x > 9) print(x / 10);
putchar(x % 10 + '0');
}
int a, b, l, r;
int A(int x) { return x * (x + 1) >> 1; }
int mn(int x, int y) { return x < y ? x : y; }
int B(int x) { return A(l - 1) * (x / r) + A(mn(l - 1, x % r)); } // 整块求和,和散块求和,相加就是答案
signed main(){
while (scanf("%lld%lld%lld%lld", &a, &b, &l, &r) != EOF) {
--r;
print(B(b) - B(a)), putchar('\n');
}
}