题目大意
陈太阳打了一个响指,这世上的数字便都减少了一半。
对于所有在
[
L
,
R
]
[L,R]
[L,R]中的正整数,陈太阳将他们都变成了除以A的余数。现在陈太阳想知道有多少个正整数X,满足对于任意正整数
i
∈
[
L
,
R
]
i∈[L,R]
i∈[L,R],都有
i
m
o
d
X
≡
(
i
m
o
d
A
)
m
o
d
X
imodX≡(i modA)modX
imodX≡(imodA)modX
给定A,L,R,请你计算有多少个满足条件的X。
输入格式
本题有多组测试。
第一行一个整数T表示测试组数,接下来每行一个测试点,三个正整数
L
,
R
,
A
L,R,A
L,R,A。
输出格式
对于每个测试点,如果有无数个满足条件的X,输出"-1"。否则输出一个数,表示有多少个X满足条件。
样例1
i
n
p
u
t
input
input
4
1 1 1
3 5 2
1 10 10
1 1 2
o
u
t
p
u
t
output
output
1
2
4
-1
样例2
i
n
p
u
t
input
input
11
64 92 77
12 83 35
59 66 38
14 46 92
25 68 62
11 29 81
9 46 28
34 82 34
33 60 18
17 62 59
529 535 66
o u t p u t output output
4
4
4
-1
4
-1
6
4
6
2
20
数据规模与约定
20%的数据保证1≤L,R,A≤100
40%的数据保证1≤L,R,A≤
1
0
5
10^5
105
另外20%的数据保证A<L
另外20%的数据保证R−L≥A
100%的数据保证T≤100 1≤L,R,A≤
1
0
12
10^{12}
1012 L≤R
时间限制: 1s
空间限制: 512MB
提示
m
o
d
mod
mod 表示模运算。a
m
o
d
mod
mod b表示a除以b的余数,比如说8
m
o
d
mod
mod 3=2。
题解
首先,我们可以知道,当A>R时直接输出-1,此时X∈(R,+∞],X∈
R
+
R^+
R+
然后由题意可列出
i
m
o
d
X
=
(
i
m
o
d
A
)
m
o
d
X
imodX=(i modA)modX
imodX=(imodA)modX
我们令i=A*p+q(0<=q<A)
那么原等式可化简为:
i
m
o
d
X
=
q
m
o
d
X
imodX=qmodX
imodX=qmodX
还可以接着化简:
(
A
∗
p
+
q
)
m
o
d
X
=
q
m
o
d
X
(A*p+q)modX=qmodX
(A∗p+q)modX=qmodX
那么最重要的一步就出来了:
A
∗
p
≡
0
(
m
o
d
X
)
A*p≡0(modX)
A∗p≡0(modX)
注意,这里的A为定值,而p随i递增的,也就是p是在变化的,
那我们X的取值就要讨论了:
①p不变
此时说明i/r为定值(
i
∈
[
L
,
R
]
i∈[L,R]
i∈[L,R])
也就是区间[L,R]全部落入一区间[A*p,A*(p+1))中
而我们要使
A
∗
p
≡
0
(
m
o
d
X
)
A*p≡0(modX)
A∗p≡0(modX),显然X为A*p的因数均可.
②p变
那么我们可以知道区间[L,R]至少跨越了一个形如[Ak,A(k+1))的区间
设[L,R]落入区间[Al,A(r+1))(l+1<r)中,那么p∈[l,r]
我们又知道
g
c
d
(
l
,
l
+
1
,
l
+
2
,
.
.
.
,
r
)
=
1
gcd(l,l+1,l+2,...,r)=1
gcd(l,l+1,l+2,...,r)=1,p对X没有约束条件
于是这里只有A对X有约束条件,那么此时X为A的因数均可
算因数用因数个数定理或者暴力均可,我用的因数个数定理.
代码
#include<set>
#include<map>
#include<ctime>
#include<queue>
#include<cmath>
#include<cstdio>
#include<vector>
#include<climits>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;
LL read(){
LL f=1,x=0;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
return x*f;
}
#define MAXN 200000
#define MAXL 1000000
#define INF 0x3f3f3f3f
#define Mod int(1e9+7)
bool check[MAXL+5];
int tot,prime[80000+5];
void Prime(){
for(int i=2;i<=MAXL;i++){
if(!check[i]) prime[++tot]=i;
for(int j=1;j<=tot&&1ll*i*prime[j]<=MAXL;j++){
check[i*prime[j]]=1;
if(i%prime[j]==0) break;
}
}
return ;
}
LL Cnt(int a){
LL ret=1;
for(int i=1;i<=tot;i++)
if(a%prime[i]==0){
LL tmp=1;
while(!(a%prime[i])) a/=prime[i],tmp++;
ret*=tmp;
}
return ret;
}
int main(){
Prime();
int T=read();
while(T--){
LL ans,l=read(),r=read(),a=read();
if(a>r){
puts("-1");
continue;
}
ans=Cnt(l/a!=r/a?a:l/a*a);
printf("%lld\n",ans);
}
return 0;
}