zoukankan      html  css  js  c++  java
  • UVA12716 GCD XOR解题报告

    题目链接:这里~~

    题目描述:输入数据组数t,接下来t行每行给定一个数字n,如样例所示格式输出满足1<=b<=a<=n且gcd(a,b)==a xor b的(a,b)二元组个数。

    输入样例#1: 

    2
    7
    20000000
    输出样例: 
    Case 1: 4
    Case 2: 34866117

    解题思路:

    首先需要知道三个性质:

    1.A^B=C , 则 A^C=B , B^C=A.

    2.(A^B)^C=A^(B^C)

    3.若A>=B, 则A-B<=A^B

    然后观察题目条件:

    等式1:GCD(A,B)=A^B=GCD(B,A-B)= C (假设一个C)

    设A>=B , A=k1*C , B=k2*C. 则 A-B=(K1-K2)*C

    当A=B ,等式1显然不成立,除非A=0.所以K1!=K2

    因为K1-K2>=1,所以A-B>=C, 又因为上面的性质为A-B<=A^B=C.

    即A-B=C

    则GCD(B,C)=C.

    我们只需要枚举C的倍数(B)就行了。

    满足了GCD(A,B)=C的限制条件,发现我们还没有用A^B=C的限制条件.

    所以我们在枚举B的时候,对于满足(B+C)^B=C的更新答案即可。

    当然A不能大于N,所以B+C<=N。

    因为T可能很多,可以发现实际上答案是可以预处理的且具有前缀和的性质。

    时间复杂度:O(Nlog(N)).

    分析:

    对于N是枚举C.

    log(n)是枚举C的倍数,每个数的倍数在N的范围内不超过N/C个,

    对于所有的数则是(N/1+N/2+N/3+...+N/N),时间复杂度为调和级数,

    所以总时间复杂度为N log(N).

    代码:

    #include<bits/stdc++.h>
    #define ll long long 
    #define R register
    using namespace std;
    const int N=3e7+5;
    int t,n;
    ll ans[N];
    inline void find()
    {
        for(R int i=1;i<=30000000;++i)//枚举c
        for(R int j=i*2;(i+j)<=30000000;j+=i)
        if((i+j)==(i^j))++ans[i+j];
        for(R int i=1;i<=30000000;++i)
        ans[i]+=ans[i-1];
    }
    int main(){
        scanf("%d",&t);
        find();
        for(R int k=1;k<=t;k++)
        {
            scanf("%d",&n);
            printf("Case %d: %lld
    ",k,ans[n]);
        }
        return 0;
    }
  • 相关阅读:
    梦断代码读后感02
    UML大战需求与分析--阅读笔记4
    UML大战需求分析--阅读笔记3
    软件需求与分析课堂讨论一
    UML大战需求分析--阅读笔记02
    UML大战需求分析--阅读笔记01
    学习进度--大三下
    问题账户需求分析
    2016年秋季阅读计划
    个人总结
  • 原文地址:https://www.cnblogs.com/sky-zxz/p/9862385.html
Copyright © 2011-2022 走看看