异或
jzoj 2298
题目大意:
定义nbnbnb数对a,ba,ba,b为gcd(a,b)=abgcd(a,b)=a^bgcd(a,b)=ab的数对,问不大于nnn的nbnbnb数对有多少对
输入样例#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 |
解题思路:
我们第一个想到的就是暴力枚举每一个数对,然后判断,时间复杂度o(n2logn)o(n^2log_n)o(n2logn)会TLE
因为axorb=ca\ xor\ b=ca xor b=c,则axorc=ba\ xor\ c=ba xor c=b,所以我们可以枚举c,然后在枚举a是c的几倍,然后用公式求出b,然后再求gcd,判断是否和c一样,时间复杂度o(n(logn)2)o(n(log_n)^2)o(n(logn)2),也会TLE
我们可以经过证明得知b=a-c
证明:
首先a−b⩽axorba-b\leqslant a\ xor\ ba−b⩽a xor b
我们距离两个二进制数:
101101011010110
110001100011000
他们相减是222
xorxorxor是14
我们可以发现xorxorxor是不同位的和
而相减是加某些不同位,再减某些不同位,最大就是所有不同位加,也不大于xorxorxor
所以a−b⩽axorba-b\leqslant a\ xor\ ba−b⩽a xor b
然后我们可以发现a−b⩽ca-b\leqslant ca−b⩽c
我们也列两个例子:
a=12a=12a=12
b=9b=9b=9
c=3c=3c=3
我们设as=a/c=4as=a/c=4as=a/c=4
bs=b/c=3bs=b/c=3bs=b/c=3
因为a,b都是c的倍数,所以a−b=as∗c−bs∗c=(as−bs)∗ca-b=as*c-bs*c=(as-bs)*ca−b=as∗c−bs∗c=(as−bs)∗c
因为aaa不等于bbb
所以as−bs⩾1as-bs\geqslant 1as−bs⩾1
所以(as−bs)∗c⩾c(as-bs)*c\geqslant c(as−bs)∗c⩾c
所以a−b⩾ca-b\geqslant ca−b⩾c
假设存在c<a−bc<a-bc<a−b
则c<a−b⩽axorbc<a-b\leqslant a\ xor\ bc<a−b⩽a xor b
不满足c=axorbc=a\ xor\ bc=a xor b
所以c=a−bc=a-bc=a−b
所以b=a−cb=a-cb=a−c
因此gcd(a,b)=gcd(a,a−c)=cgcd(a,b)=gcd(a,a-c)=cgcd(a,b)=gcd(a,a−c)=c
所以我们只需判断是否有c=axorbc=a\ xor \ bc=a xor b即可
代码:
#include<cstdio>
using namespace std;
int n,a,b,ans;
int main()
{scanf("%d",&n);for (int i=1;i<=(n>>1);++i)for (int j=2;i*j<=n;++j){a=i*j;//求出ab=a-i;//相减得到bif (i==(a^b))//判断c是否等于a^bans++;}printf("%d",ans);
}