GCD XOR UVA - 12716

问题

分析

这道题是我自己做不出来的
记录下思路
这道题肯定不能同时枚举a,b,否则肯定TLE,所以只枚举a,然后计算b。
思路:这涉及到gcd和xor之间的关系,设 a   x o r   b = c a\space xor\space b=c a xor b=c,那么由异或的性质,可以得到 a   x o r   c = b a\space xor\space c=b a xor c=b。所以可以枚举a和它的因数c作为gcd,然后计算出b,最后验证是否有 g c d ( a , b ) = c gcd(a,b)=c gcd(a,b)=c.这种做法的时间复杂度:枚举a和它的因数c是O(nlgn),然后gcd是O(lgn),所以总的是 O ( n ( l o g n ) 2 ) O(n(logn)^2) O(n(logn)2)
继续优化,发现满足 g c d ( a , b ) = c = a   x o r   b gcd(a,b)=c=a\space xor\space b gcd(a,b)=c=a xor b的元素都满足a-b=c
证明:a-b<=a xor b且a-b>=c,c=gcd(a,b)=a xor b,所以a-b=c
所以,可以枚举a,c,计算b=a-c,验证b=a^c是否成立,时间时O(lgn)

#include <cstring>
#include <cstdio>
#include <vector>
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
typedef long long ll;
const int maxn=30000000+1;
int cnt[maxn],s[maxn];  //cnt:前缀,cnt[i],a=i时的情况数
int main(void){
    //类似埃氏筛的枚举方式
    for(int c=1;c<maxn;++c){  //枚举c
        for(int a=c*2;a<maxn;a+=c){  //枚举a
            if(a-c==(a^c)){
                cnt[a]++;
            }
        }
    }
    for(int i=1;i<maxn;++i) s[i]=s[i-1]+cnt[i];

    int T=0,kase=0,n=0;
    scanf("%d",&T);
    while(kase<T){
        scanf("%d",&n);
        printf("Case %d: %d\n",++kase,s[n]);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值