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

2014-09-02 19:13:32

12716 GCD 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)。

思路:第二版小白书例题,但是前两次交都是TLE。。。借鉴书里和别人的博客

 

  有几个结论:(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。

 1 /*************************************************************************
 2     > File Name: 12716.cpp
 3     > Author: Nature
 4     > Mail: 564374850@qq.com 
 5     > Created Time: Tue 02 Sep 2014 04:17:33 PM CST
 6 ************************************************************************/
 7 
 8 #include <cstdio>
 9 #include <cstring>
10 #include <cstdlib>
11 #include <cmath>
12 #include <iostream>
13 #include <algorithm>
14 using namespace std;
15 typedef long long ll;
16 const int RA = 30000000;
17 
18 int T,N;
19 int ans[RA + 5];
20 
21 void Init(){
22     int top = RA >> 1,b;
23     for(int c = 1; c <= top; ++c){
24         for(int a = c + c; a <= RA; a += c){
25             b = a - c;
26             if((a ^ b) == c) ++ans[a];
27         }
28     }
29     for(int i = 2; i <= RA; ++i) ans[i] += ans[i - 1];
30 }
31 
32 int main(){
33     Init();
34     scanf("%d",&T);
35     for(int t = 1; t <= T; ++t){
36         scanf("%d",&N);
37         printf("Case %d: %d\n",t,ans[N]);
38     }
39     return 0;
40 }

 

posted @ 2014-09-02 19:27  Naturain  阅读(1282)  评论(0编辑  收藏  举报