Educational Codeforces Round 86 (Rated for Div. 2)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 aa and bb, and qq queries. The ii-th query consists of two numbers lili and riri, and the answer to it is the number of integers xx such that li≤x≤rili≤x≤ri, and ((xmoda)modb)≠((xmodb)moda)((xmoda)modb)≠((xmodb)moda). Calculate the answer for each query.

Recall that ymodzymodz is the remainder of the division of yy by zz. For example, 5mod3=25mod3=2, 7mod8=77mod8=7, 9mod4=19mod4=1, 9mod9=09mod9=0.

扫描二维码关注公众号,回复: 11887273 查看本文章

Input

The first line contains one integer tt (1≤t≤1001≤t≤100) — the number of test cases. Then the test cases follow.

The first line of each test case contains three integers aa, bb and qq (1≤a,b≤2001≤a,b≤200; 1≤q≤5001≤q≤500).

Then qq lines follow, each containing two integers lili and riri (1≤li≤ri≤10181≤li≤ri≤1018) for the corresponding query.

Output

For each test case, print qq integers — the answers to the queries of this test case in the order they appear.

Example

input

Copy

2
4 6 5
1 1
1 3
1 5
1 7
1 9
7 10 2
7 8
100 200

output

Copy

0 0 0 2 4 
0 91 

题意:

求区间内满足的数字个数。

思路:

这题可以选择打表看看规律,比如第二个样例

7 10

100 200

我们现在假设a  > b。

你会发现140 ~ 149都满足 x mod a mod b = x mod b mod a。

在200 ~ 300中210 ~ 219, 280 ~ 289都满足这个条件。

很显然的,从每个a 跟 b的公倍数开始后a个都是满足等于的。

所以我们可以计算出满足相等的再用区间长度减去相等的,对于小于公倍数的区间

我们可以直接暴力计算。

至于为什么是这个,对于某个数字x,我们假设增加了u个,当x为a的倍数的时候显然

(x + u) % a = x % a + u % a = u, 所以左边就等于u % b

对于两次mod,如果先mod小的,mod完的结果肯定是小于b的,所以再mod a没有意义。

右边就是(x + u) % b = x % b + u % b = u % b

所以左边等于右边。特殊的是当a % b == 0时,所有数字都满足相等的条件。

我们计算相等的,去掉就是不相等的了。

#include <bits/stdc++.h>
#include <unordered_map>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;

#ifdef LOCAL
#define debug(x) cout << "[" __FUNCTION__ ": " #x " = " << (x) << "]\n"
#define TIME cout << "RuningTime: " << clock() << "ms\n", 0
#else
#define TIME 0
#endif
#define hash_ 1000000009
#define Continue(x) { x; continue; }
#define Break(x) { x; break; }
const int mod = 998244353;
const int N = 2e5 + 10;
const int INF = 0x3f3f3f3f;
const ll LINF = 0x3f3f3f3f3f3f3f3f;
#define gc p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1000000, stdin), p1 == p2) ? EOF : *p1++;
inline int read(){ static char buf[1000000], *p1 = buf, *p2 = buf; register int x = false; register char ch = gc; register bool sgn = false; while (ch != '-' && (ch < '0' || ch > '9')) ch = gc; if (ch == '-') sgn = true, ch = gc; while (ch >= '0'&& ch <= '9') x = (x << 1) + (x << 3) + (ch ^ 48), ch = gc; return sgn ? -x : x; }
ll fpow(ll a, int b, int mod) { ll res = 1; for (; b > 0; b >>= 1) { if (b & 1) res = res * a % mod; a = a * a % mod; } return res; }
ll a, b, d;
ll sum[N];
ll gcd(ll a, ll b)
{
	return b == 0 ? a : gcd(b, a % b);
}
ll lcm(ll a, ll b)
{
	return a * b / gcd(a, b);
}
ll calc2(ll n)
{
	ll u = n / d;
	ll sum = u * a;
	if (u == 0)
		return 0;
	if (u * d + a - 1 > n)
		sum -= (u * d + a - 1 - n);
	return sum;
}
int main()
{
#ifdef LOCAL
	freopen("E:/input.txt", "r", stdin);
#endif
	int t;
	cin >> t;
	while (t--)
	{
		ll q;
		cin >> a >> b >> q;
		if (a < b)
			swap(a, b);
		int flag = 1;
		if (a % b == 0)
		{
			flag = 0;
		}
		for (int i = 1; i <= 200 * 200; i++)
		{
			sum[i] = sum[i - 1] + (i % a % b == i % b % a);
		}
		while (q--)
		{
			if (flag == 0)
			{
				cout << "0 ";
			}
			ll L, R;
			cin >> L >> R;
			d = lcm(a, b);
			ll ans = R - L + 1 - (calc2(R) - calc2(L - 1));
			if (min(d - 1, R) >= L)
				ans -= sum[min(d - 1, R)] - sum[L - 1];
			if (flag)
				cout << ans << " ";
		}
		cout << endl;
	}
	return TIME;
}

猜你喜欢

转载自blog.csdn.net/weixin_43731933/article/details/105794571