题意
输入整数n(1<=n<=3*107),有多少对整数(a,b)满足:1<=b<=a<=n,且gcd(a,b)=a XOR b。例如:n=7时,有4对:(3,2),(5,4),(6,4),(7,6)
分析
本题的主要想法就是找到一个沟通gcd(a,b)和a^b的桥梁
- a^b≥a-b。口头化证明:假如二进制位上相同,那么都是0,加入二进制位上不同,前者一定是1,后者可能是1(1-0),也有可能借位导致数位减少(0-1)
- a-b≥gcd(a,b)。由九章算术·更相减损术可得gcd(a,b)=gcd(a,a-b)=gcd(b,a-b)。显然a-b≥gcd(a,a-b),得证
我们现在已知gcd(a,b)=a^b,根据夹逼法,a^b=a-b=gcd(a,b)=gcd(a,a-b)
换言之,a^b等于a-b,还有取等前提a-b是a的因子
因此我们枚举a-b,求得它的所有倍数,再判断a-b=a^b是否成立。时间复杂度O(N+N/2+N/3+……+N/N)=O(N logN)
注意打好括号,不然等着WA几发吧
代码
- #include<bits/stdc++.h>
- using namespace std;
- #define N 30000003
- int t,n;
- int ans[N];
- int main()
- {
- for(int i=1;i<N;i++)
- {
- for(int j=i*2;j<N;j+=i)
- if((j^(j-i))==i)
- ans[j]++;
- ans[i]+=ans[i-1];
- }
- scanf("%d",&t);
- for(int i=1;i<=t;i++)
- {
- scanf("%d",&n);
- printf("Case %d: %d\n",i,ans[n]);
- }
- }
原文地址:https://www.cnblogs.com/NSD-email0820/p/9862530.html
时间: 2024-10-01 08:07:10