题目描述
给定两个数字a,b,有q次询问,每次询问给出两个数字 l , r, 求 l 到 r 的范围内有多少数x使得 x % a % b != x % b % a
思路
要求x % a % b和 x % b % a,可以发现每次的循环区间是lcm(a,b),可以通过循环节解决问题。
因为 l,r 的范围在1e18, 考虑 l ~ r的范围就想到了前缀和的思维。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 4e4 + 10;
LL f[N];
LL a, b, q, num;
LL gcd(LL a, LL b) {
return b == 0 ? a : gcd(b, a % b);
}
LL cacl(LL x) {
return f[num] * (x / num) + f[x % num];
}
void solve() {
scanf("%lld %lld %lld", &a, &b, &q);
if(a < b) swap(a, b);
num = a / gcd(a, b) * b;
for(int i = 1; i <= num; i++) {
f[i] = f[i - 1];
if(i % a % b != i % b % a) f[i]++;
}
while(q--) {
LL l, r;
LL cnt = 0;
scanf("%lld %lld", &l, &r);
printf("%lld ", cacl(r) - cacl(l - 1));
}
puts("");
}
int main() {
// freopen("in.txt", "r", stdin);
int t;
scanf("%d", &t);
while(t--) {
solve();
}
return 0;
}