基准时间限制:1 秒 空间限制:131072 KB 分值: 80
难度:5级算法题
给出一段从A - B的区间S(A,B为整数),这段区间内的整数可以随便使用任意次。再给出一段从X - Y的区间T,问用区间S中的整数做加法,可以覆盖区间T中多少个不同的整数。
例如:区间S为8 - 10,区间T为3 - 20。在3 - 20中,整数8(8),9(9),10(10),16(8+8),17(8+9),18(9+9),19(9+10),20(10+10)。可以被区间S中的数覆盖,因此输出8。
Input
第1行:一个数T,表示后面用作输入测试的数的数量。(1 <= T <= 1000) 第2 - T + 1行:每行4个数:A, B , X, Y,中间用空格分隔。(1 <= A < B <= 10^18, 1 <= X < Y <= 10^18)
Output
输出共T行,每行1个数,区间[X,Y]中可以由A-B中的整数相加得到的不同整数的数量。
Input示例
1 8 10 3 20
Output示例
8
#include <bits/stdc++.h>
#define MOD 1000000007
#define maxn 505
#define INF 1e18
using namespace std;
typedef long long ll;
ll a, b, x, y;
ll solve1(ll k, ll c){
ll d;
if((b - a) > INF / k)
d = INF;
else
d = (b - a) * k;
if(d >= a - 1)
d = a - 1;
ll e = c - k * a;
if(d >= e) {
return d - e + 1;
}
return 0;
}
ll solve2(ll k, ll c){
ll d;
if((b - a) > INF / k)
d = INF;
else
d = (b - a) * k;
if(d >= c - k * a)
d = c - k * a;
return d + 1;
}
ll solve3(ll k1, ll k2){
k1++;
k2--;
ll e = a - 1;
ll h = e / (b - a);
if(k1 > h)
return (k2 - k1 + 1) * a;
if(k1 >= h && k1 < k2)
return (k2 - k1) * a + (h * (b - a) + 1 + k1 * (b - a) + 1) * (k1 - h + 1) / 2;
if(h >= k2)
return (k1 * (b - a) + 1 + k2 * (b - a) + 1) * (k2 - k1 + 1) / 2;
}
int main(){
//freopen("in.txt", "r", stdin);
int t;
scanf("%d", &t);
while(t--){
scanf("%I64d%I64d%I64d%I64d", &a, &b, &x, &y);
if(x < a)
x = a;
if(a > y)
puts("0");
else{
ll k1 = x / a;
ll k2 = y / a;
if(k1 == k2){
ll d;
if((b - a) > INF / k1)
d = INF;
else
d = (b - a) * k1;
x -= k1 * a;
y -= k2 * a;
if(d < x)
puts("0");
else{
if(d >= y)
d = y;
printf("%I64d\n", d - x + 1);
}
}
else{
ll ans = 0;
ans += solve1(k1, x);
ans += solve2(k2, y);
if(k2 - k1 > 1)
ans += solve3(k1, k2);
printf("%I64d\n", ans);
}
}
}
return 0;
}