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≤1018) 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两个数和q组询问,每组询问给出区间[l,r],求在[l,r]这个区间里的数有多少个能使得(x%a)%b!=(x%b)%a成立。
这道题。。。。哎!不说了。
题目分析:
通过分析(打表),我们可以发现这样一个规律:
以样例二为例
在1-200区间内不满足(x%7)%10!=(x%10)%7这个条件的数有:1-9,70-79,140-149这九个数。7和10的最小公倍数 70。
由此我们可以发现:不满足条件的数所在的区间为[k * a和b的最小公倍数,k * a和b的最小公倍数+max(a,b)] (k为整数,且k可以等于0).
这样时间复杂度可以优化不少,但还是不够(我当时就只是搞到了这里)。
我们还需要加一个优化:前缀和优化(无敌的前缀和)
用一个数组来存一个周期中,有多少数是满足条件的,并用前缀和处理。这样我们就可以求出1-x(x为任意整数)中有多少数是符合条件的。答案用算出的1一r和1一l-1中符合条件的数相减即可。
1-x中有多少符合条件的数的求法:先算出x覆盖了多少个完整的周期,即:f[n-1]*(x/n)。再加上剩余部分f[x%n]即可。
ac代码如下:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#include <iomanip>
#define LL long long
using namespace std;
const int N=1e5+5;
int f[N];
int gcd(int a,int b) //求最小公倍数
{
return b?gcd(b,a%b):a;
}
int lcm(int a,int b) //利用最小公倍数求出最大公约数
{
return a*b/gcd(a,b);
}
LL cal(LL x,LL n) //计算1-x中符合条件的数
{
return f[n-1]*(x/n)+f[x%n];
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int a,b,q;
scanf("%d%d%d",&a,&b,&q);
int n=lcm(a,b); //n为周期长度
for(int i=1;i<n;i++) //前缀和优化过的记录周期的数组
{
f[i]=f[i-1];
if((i%a)%b!=(i%b)%a) f[i]++;
}
while(q--)
{
LL l,r; //l,r的范围爆int
scanf("%lld%lld",&l,&r);
//算出答案并输出即可
printf("%lld ",cal(r,n)-cal(l-1,n));
}
}
return 0;
}