UVA 12716 gcd xor

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

#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
#define fo freopen("in.txt","r",stdin)
#define fc fclose(stdin)
#define fu0(i,n) for(i=0;i<n;i++)
#define fu1(i,n) for(i=1;i<=n;i++)
#define fd0(i,n) for(i=n-1;i>=0;i--)
#define fd1(i,n) for(i=n;i>0;i--)
#define mst(a,b) memset(a,b,sizeof(a))
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d %d",&n,&m)
#define ss(s) scanf("%s",s)
#define sddd(n,m,k) scanf("%d %d %d",&n,&m,&k)
#define pans() printf("%d\n",ans)
#define all(a) a.begin(),a.end()
#define sc(c) scanf("%c",&c)
#define we(a) while(scanf("%d",&a)!=EOF)
const int maxn=30000005;
const double eps=1e-8;
int ans[maxn];
int main()
{
    int n,cas,b;
    cin>>cas;
    memset(ans,0,sizeof(ans));
    for(int c=1; c<=(maxn>>1); c++)
    {
        for(int a=c+c; a<=maxn; a+=c)
        {
            b=a-c;
            int t=a^b;
            if(t==c)
            {
                //cout<<a<<" "<<b<<endl;
                ++ans[a];
            }
        }
    }
    for(int i=2;i<=maxn;i++)
    {
        ans[i]+=ans[i-1];
    }
    for(int i=1; i<=cas; i++)
    {
        cin>>n;
        cout<<"Case "<<i<<": "<<ans[n]<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/dilly__dally/article/details/81032960
今日推荐