

十分有趣的一道题……
先证明两个式子(假设$a \gt b$)……
$$\gcd(a,b) \le a-b$$
证:$\gcd(a,b)=\gcd(a,a-b) \le \min(a,a-b) \le a-b$
$$a \oplus b \ge a-b$$
对于$a$和$b$的某个相对应的二进制位,如果都是$0$或者都是$1$,$a \oplus b$一定不差于$a-b$,因为$0 \oplus 0=0,1 \oplus 1=0$且$0-0=0,1-1=0$
如果一个是$1$一个是$0$,那么依然$a \oplus b$一定不差于$a-b$,因为$1 \oplus 0 = 1$且$1-0=0$,同时$0 \oplus 1 = 1$,然而$0-1=-1$会引发退位
综上,$a \oplus b \ge a-b$
因此如果要求$\gcd(a,b)=a \oplus b$,则$\gcd(a,b)=a-b=a \oplus b$
因为$\gcd(a,b)=\gcd(a,a-b)=a-b$,所以$a$是$a-b$的倍数,所以可以枚举$a-b$,然后再枚举$a=k(a-b)$,其中$k \ge 2$
而且有$b=a-(a-b)=k(a-b)-(a-b)=(k-1)(a-b)$
之后只需要判断$k(a-b) \oplus (k-1)(a-b)=a-b$是否成立即可


1 #include <bits/stdc++.h> 2 using namespace std; 3 int n, ans; 4 int main() { 5 scanf("%d", &n); 6 for(int i = 1 ; i <= n ; ++ i) 7 for(int j = i + i ; j <= n ; j += i) 8 if((j ^ (j - i)) == i) 9 ++ ans; 10 printf("%d\n", ans); 11 }
本文深入探讨了NOIP2017提高组模拟赛中一道涉及数学证明与算法实现的题目。通过严谨的数学推导,证明了两个关键不等式,并给出了一种基于枚举的算法解决方案。文章详细解释了如何利用二进制位运算的性质来优化求解过程。
318

被折叠的 条评论
为什么被折叠?



