【数学】异或
異或
題目大意
問你不小于nnn的數對(a,b)(a,b)(a,b),有多少個滿足gcd(a,b)=a⊕bgcd(a,b)=a \oplus bgcd(a,b)=a⊕b
輸入樣例#1
12輸出樣例#1
8輸入樣例#2
123456輸出樣例#2
214394數據范圍
| 1 | 10 |
| 2 | 100 |
| 3 | 1000 |
| 4 | 5000 |
| 5 | 10000 |
| 6 | 100000 |
| 7 | 500000 |
| 8 | 1000000 |
| 9 | 5000000 |
| 10 | 20000000 |
解題思路
我們設c=gcd(a,b)c=gcd(a,b)c=gcd(a,b)
我們可以枚舉ccc
然后枚舉aaa是ccc的多少倍
由此得出a,ca,ca,c
我們可以通過gcdgcdgcd求出bbb然后判斷是否滿足a⊕b=ca \oplus b=ca⊕b=c
但是這個時間復雜度過大,我們要進行優化
我們先證明a?b?a⊕ba-b \leqslant a \oplus ba?b?a⊕b
我們觀察以下兩個字符串(x>y)(x>y)(x>y)
x:x:x: 11001
y:y:y: 00101
xor:xor:xor: 11100
1...對于x,yx,yx,y都是1的位xorxorxor和?-?得出結果都是0
2...對于只有yyy是1的位
因為a>ba>ba>b,所以在更高的位肯定有只有xxx是1的位,這樣減出來的結果才可能是正數
因此?-?得出的結果是更高一位只有xxx是1的位減這一位
而xorxorxor得出的是這兩位的和
3...對于只有xxx是1且無需用去減的位xorxorxor和?-?得出結果都是1
綜上所述,a?b?a⊕ba-b \leqslant a \oplus ba?b?a⊕b
現在我們來證明c?a?bc \leqslant a-bc?a?b
因為c=gcd(a,b)c=gcd(a,b)c=gcd(a,b)
我們設
a=c?asa=c*asa=c?as
b=c?bsb=c*bsb=c?bs
若a=ba=ba=b則
gcd(a,b)=1gcd(a,b)=1gcd(a,b)=1
a⊕b=0a \oplus b=0a⊕b=0
gcd(a,b)≠a⊕bgcd(a,b) \neq a \oplus bgcd(a,b)?=a⊕b
∴a≠b\therefore a \neq b∴a?=b
∵a≠b且a?b\because a \neq b 且a \geqslant b∵a?=b且a?b
a>ba > ba>b
∵as>bs\because as > bs∵as>bs
as?bs?1as - bs\geqslant 1as?bs?1
(as?bs)×c?c(as - bs)\times c \geqslant c(as?bs)×c?c
a?b?ca-b\geqslant ca?b?c
若a?b≠ca-b\neq ca?b?=c
則c<a?b?a⊕bc < a-b \leqslant a \oplus bc<a?b?a⊕b
c<a⊕bc<a \oplus bc<a⊕b
無法滿足c=a⊕bc=a \oplus bc=a⊕b
∴a?b=c\therefore a-b=c∴a?b=c
這樣我們通過b=a?cb=a-cb=a?c求出bbb
然后判斷ccc是否等于a⊕ba \oplus ba⊕b即可
代碼
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ll long long using namespace std; int n, a, b, ans; int main() {scanf("%d", &n);for (int i = 1; i <= n / 2; ++i)for (int j = 2; i * j <= n; ++j){a = i * j;b = a - i;//求bif (i == (a^b)) ans++;}printf("%d", ans);return 0; }總結
- 上一篇: 【数学期望】【LCA】【树形DP】树
- 下一篇: 【最小生成树】灌水