题意:给定整数
n
n
n ,求满足
1
≤
b
≤
a
≤
n
1 \leq b \leq a \leq n
1≤b≤a≤n且
gcd
(
a
,
b
)
=
a
⊕
b
\gcd(a,b)=a \oplus b
gcd(a,b)=a⊕b的二元组
(
a
,
b
)
(a,b)
(a,b) 的数量.
因为当
a
=
b
a=b
a=b 时无解,所以下面默认
a
>
b
a>b
a>b.
这里我们有两个结论,下面依次给出并证明:
结论1 :
gcd
(
a
,
b
)
≤
a
−
b
\gcd(a,b)\leq a-b
gcd(a,b)≤a−b
证明:令
gcd
(
a
,
b
)
=
k
,
a
=
m
k
,
b
=
n
k
(
m
≥
n
)
\gcd(a,b)=k,a=mk,b=nk(m \geq n)
gcd(a,b)=k,a=mk,b=nk(m≥n),则有
a
−
b
=
(
m
−
n
)
k
≥
k
a-b=(m-n)k \geq k
a−b=(m−n)k≥k 即
gcd
(
a
,
b
)
≤
a
−
b
\gcd(a,b)\leq a-b
gcd(a,b)≤a−b
结论2:
a
−
b
≤
a
⊕
b
a-b\leq a\oplus b
a−b≤a⊕b
证明:由于异或本质为不进位加法,所以
a
⊕
b
≤
a
+
b
a\oplus b \leq a+b
a⊕b≤a+b,所以
a
=
a
⊕
b
⊕
b
≤
a
⊕
b
+
b
a=a\oplus b\oplus b\leq a\oplus b +b
a=a⊕b⊕b≤a⊕b+b,移项可得
a
−
b
≤
a
⊕
b
a-b\leq a\oplus b
a−b≤a⊕b.
再看这道题,要求
gcd
(
a
,
b
)
=
a
⊕
b
\gcd(a,b)=a \oplus b
gcd(a,b)=a⊕b,于是
gcd
(
a
,
b
)
=
a
−
b
=
a
⊕
b
\gcd(a,b)=a-b=a \oplus b
gcd(a,b)=a−b=a⊕b,可以现预处理出每一个
a
−
b
a-b
a−b.
code:
#include<bits/stdc++.h>
using namespace std;
int sum[30005000];
int t,n;
int main(){
for(int k=1;k<=30000000;++k)//k即为a-b
for(int x=2*k;x<=30000000;x+=k){//枚举a,枚举k的倍数是为了保证gcd(a,b)=a-b
int y=x-k;
if((x^y)==k)++sum[x];
}
for(int i=1;i<=30000000;++i)sum[i]+=sum[i-1];
scanf("%d",&t);
for(int i=1;i<=t;++i){
scanf("%d",&n);
printf("Case %d: %d\n",i,sum[n]);
}
return 0;
}//完结撒花owo