C. Yet Another Counting Problem
time limit per test :3.5 seconds memory limit per test :256 megabytes
input :standard input output :standard output
You are given two integers a and b, and q queries. The i-th query consists of two numbers li and ri, and the answer to it is the number of integers x such that li≤x≤ri, and ((xmoda)modb)≠((xmodb)moda). Calculate the answer for each query.
Recall that ymodz is the remainder of the division of y by z. For example, 5mod3=2, 7mod8=7, 9mod4=1, 9mod9=0.
Input
The first line contains one integer t (1≤t≤100) — the number of test cases. Then the test cases follow.
The first line of each test case contains three integers a, b and q (1≤a,b≤200; 1≤q≤500).
Then q lines follow, each containing two integers li and ri (1≤li≤ri≤) for the corresponding query.
Output
For each test case, print q integers — the answers to the queries of this test case in the order they appear.
Example
input
2
4 6 5
1 1
1 3
1 5
1 7
1 9
7 10 2
7 8
100 200
output
0 0 0 2 4
0 91
题目大意
给定a, b,问区间l到r中有多少数x满足 x % a % b != x % b % a
思路
我们只要计算1 - lcm(a, b)(a, b的最小公倍数)的数,然后计算前缀和sum,那么
ll x = (l - 1) / c * sum[c] + sum[(l - 1) % c];
ll y = r / c * sum[c] + sum[r % c];
ans = y - x;
其中c为a,b的最小公倍数。
代码
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define fi first
#define se second
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef pair<ll, ll> pll;
const int mod = 1e9 + 7;
const int N = 2e5 + 10;
const int INF = 0x3f3f3f3f;
ll qpow(ll base, ll n){ll ans = 1; while (n){if (n & 1) ans = ans * base % mod; base = base * base % mod; n >>= 1;} return ans;}
ll gcd(ll a, ll b){return b ? gcd(b, a % b) : a;}
ll sum[50000];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t;
cin >> t;
while (t --){
ll a, b, q;
cin >> a >> b >> q;
ll c = a * b / gcd(a, b);
sum[0] = 0;
for (int i = 1; i <= c; ++ i){
sum[i] = sum[i - 1];
if (i % a % b != i % b % a){
sum[i] += 1;
}
}
ll l, r;
ll ans;
for (int i = 1; i <= q; ++ i){
cin >> l >> r;
ll x = (l - 1) / c * sum[c] + sum[(l - 1) % c];
ll y = r / c * sum[c] + sum[r % c];
ans = y - x;
cout << ans << ' ';
}
cout << '\n';
}
return 0;
}