传送门:https://cn.vjudge.net/problem/UVA-12716
题意:
输入整数n(1<=n<=30000000),有多少对整数(a,b)满足:1<=b<=a<=n,且gcd(a,b)=a XOR b。例如n=7时,有4对:(3,2),(5,4),(6,4),(7,6)。
分析:
看上去很难,因为gcd和xor似乎没啥关联。不过xor的好处是:a xor b=c,则a xor c=b。所以可以枚举a和c,然后算出b=a xor c,最后验证是否有gcd(a,b)=c。时间复杂度如何?约为O(n(logn)^2)。
还可以优化。上述程序写出来后,可以打印一些满足gcd(a,b)=a xor b=c的三元组(a,b,c),然后很容易发现:c=a-b。
证明如下:不难发现a-b<=a xor b,且a-b>=c。假如存在c使得a-b>c,则c<a-b<=a xor b,这与c=a xor b矛盾。
于是时间复杂度降为了O(nlogn)。
还有一个坑点,时间要求为5s,需要预处理!!!
代码:
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
const ll maxn=3e7+10;
ll f[maxn];
int gcd(int a,int b){
return b==0?a:gcd(b,a%b);
}
int main(){
int t,n,a,b,c;
memset(f,0,sizeof(f));
for(c=1;c<=maxn/2;c++){
for(a=2*c;a<maxn;a+=c){
b=a-c;
if((a xor b)==c){
f[a]++;
}
}
}
for(int i=1;i<maxn;i++)
f[i]+=f[i-1];
scanf("%d",&t);
for(int k=1;k<=t;k++){
scanf("%d",&n);
printf("Case %d: %lld\n",k,f[n]);
}
return 0;
}
本文详细解析了UVA-12716题目,探讨了如何寻找满足特定条件的整数对(a,b),并分享了一种高效算法实现,将时间复杂度从O(n(logn)^2)优化到O(nlogn)。
4459

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



