2013 Asia - Dhaka GCD XOR 数学,gcd ,异或 (uvaLive 6657 - GCD XOR)

来源:互联网 发布:大数据前十大公司排名 编辑:程序博客网 时间:2024/04/28 13:43


想不出来真失败,

总结一下这个题目主要是在这几点上:

1.很容易想到枚举a,b,然后判断__gcd(a,b)是否等于a^b。也很容易发现这样做是完全不行的。(1/1)

2.分析出gcd和xor其实并没有太大关系(1/1)

3.然后分析出gcd和xor并没有关系,而且时间不够,那么就要充分利用xor或者gcd的性质。(2/2)

4.鉴于1和3,那么我们可以换个枚举的方式,枚举a和a的因子,或者枚举c和c的倍数。然后去找b。(1/1)

5.由于想不出合适的解法,那么我们可以打表找规律(1/2)

1)首先找n和ans[n]的规律,只能得出ans[n-1]和ans[n]相差很小,ans[x]单增,然而得不到准确公式(1/1)

2) 虽然得不到准确公式,但是不能就此停止,还是可以找到一些重要性质的:

  如果不是单纯的计算ans[n],而是看一下满足条件的a,b,c的性质,那么可以得出a-b=c。(0/1)

6.数论基础十分薄弱,导致书上给出a-b=c的证明是看了半天,这个也会影响解题  (0/3)。

1) 比如说 a-b>=gcd ,为什么呢?因为gcd|a,gcd|b,so gcd|a-b,而且a一定!=b,so gcd>=a-b  (0/1)

2)又比如 a-b<=a xor b  (这里a>=b) ,想想很显然                                              (0/1)

3)    由1)、2)   gcd<=a-b<=a xor b ,所以如果满足条件必有c=gcd=a-b=a xor b。(0/1)

7.对筛法的时间复杂度比较模糊 (0/1)


书上说这个复杂度大约为O(nlogn),我却认为远远不止。

    for(int c=1;c<=maxn;c++)    {        for(int a=2*c;a<=maxn;a+=c)        {            int b=a-c;            if(c== (a^b) )            {                dp[a]++;            }        }    }

8.由此得出结论,枚举a、c(保证b一定是c的倍数),b=a-c 判断a xor b ==c (0/1)






#include<bits/stdc++.h>using namespace std;#define all(x) (x).begin(), (x).end()#define for0(a, n) for (int (a) = 0; (a) < (n); (a)++)#define for1(a, n) for (int (a) = 1; (a) <= (n); (a)++)typedef long long ll;typedef pair<int, int> pii;const int INF =0x3f3f3f3f;const int maxn= 30000000   ;int n;int ans[maxn+10];int dp[maxn+5];int init(){    for(int c=1;c<=maxn;c++)    {        for(int a=2*c;a<=maxn;a+=c)        {            int b=a-c;            if(c== (a^b) )            {                dp[a]++;            }        }    }    ans[0]=0;   for(int i=1;i<=maxn;i++)   {       ans[i]=ans[i-1]+dp[i];   }}int main(){   init();   int T,kase=0;scanf("%d",&T);   while(T--)   {       scanf("%d",&n);       printf("Case %d: %d\n",++kase,ans[n] );   }   return 0;}


找规律:

#include<bits/stdc++.h>using namespace std;#define all(x) (x).begin(), (x).end()#define for0(a, n) for (int (a) = 0; (a) < (n); (a)++)#define for1(a, n) for (int (a) = 1; (a) <= (n); (a)++)typedef long long ll;typedef pair<int, int> pii;const int INF =0x3f3f3f3f;//const int maxn=    ;int get(int x){    int ans=0;    for(int i=1;i<=x;i++)    {        for(int j=1;j<=i;j++)        {            if(__gcd(i,j)== (i^j) )            {                cout<<i<<" "<<j<<" "<<(i^j)<<endl;                ans++;            }        }    }    return ans;}int main(){    get(100);/*    for(int i=1;i<=100;i++)    {        printf("%d : %d\n",i,get(i));    }*/   return 0;}


0 0