【Educational Codeforces Round 86 (Rated for Div. 2)/1342 C】- C. Yet Another Counting Problem - 打表前缀和

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≤10^{18}) 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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值