JZOJ 5197. 【NOIP2017提高组模拟7.3】C


十分有趣的一道题……

先证明两个式子(假设$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 }
JZOJ 5197. 【NOIP2017提高组模拟7.3】C

转载于:https://www.cnblogs.com/KingSann/articles/9481778.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值