Uva 12716-GCD XOR(数论,枚举,xor)

原题链接:点击打开链接

题意:输入整数n(1<=n<=3千万),有多少对整数(a,b)满足:1<=b<=a<=n,且gcd(a,b)=a XOR b。例如:n=7时,有4对:(3,2),(5,4),(6,4),(7,6)。

思路:

  有几个结论:(1)若 a xor b = c,则 a xor c = b。

        (2)a - b <= a xor b,(a >= b)

        (3)若 gcd(a,b)= a xor b = c ,(a >= b),由(2)得:a - b <= c。

            再令 a = k1×c,b = k2 × c,(k1 >= k2),所以 a - b = (k1 - k2)× c,所以 a - b >= c。总:a - b = c

           (这里若k1 = k2,那么 a = b,那么 a xor b = 0)

  然后就是怎么枚举的问题了,要保证计算量尽量小,如果枚举a,就要枚举a的所有因数,有些数因为可能是多个数的因数,会被重复考虑很多次。所以这里要枚举因数 c ,a = k × c(k >= 2) 这样每个因数只枚举一遍,再检验b。

/*************************************************************************
    > File Name: 12716.cpp
    > Author: Clannad
    > Mail: 821199012@qq.com
    > Created Time: Mon 11 July 2016 02:31:33 PM
************************************************************************/
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <algorithm>
#include <sstream>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include<string>
#include <ctime>
using  namespace std;
typedef  long  long  ll;
const int inf=0x3f3f3f3f;
const int maxn=3e7;
int ans[maxn+5];
int T,n,Case=0;
void  init(){
    int top=maxn>>1;
    int b;
    for(int c=1 ; c<=top ; c++){
        for(int a=c+c ; a<=maxn ; a+=c){
            b=a-c;
            if(c==(a^b))ans[a]++;
        }
    }
    for(int i=2 ; i<=maxn ; i++)
        ans[i]+=ans[i-1];
}
int main()
{
    std::ios::sync_with_stdio(false);
//    #ifndef ONLINE_JUDGE
//        freopen("inE.txt", "r", stdin);
//    #endif
    init();
    cin>>T;
    while(T--){
        cin>>n;
        printf("Case %d: %d\n",++Case,ans[n]);
    }
    return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值