• YY 的 GCD


    题目背景
    是一个热爱学习的奆佬,他尤其喜欢 gcd 和位运算。但是这天,老师给他出了一道非
    常难的题, YY 知道仅凭自己的力量是做不出这道题的,于是他来请教你,希望你能设计
    一个程序来帮助他。
    YY
    题目描述
    给定你一个正整数 n ,求满足 1 ≤ b ≤ a ≤ n 且 gcd(a, b) == a xor b 的 a, b 的对数。
    输入格式
    从文件 gcd.in 中读入
    第一行一个正整数 T 表示数据组数。
    接下来 T 行每行一个正整数 n ,含义如上。
    输出格式
    输出到 gcd.out 文件中
    共 n 行,格式为 Case x: ans ,其中 x 表示是是第几组数据, ans 表示该组数据的答案。
    (建议复制粘贴)
    样例
    输入
    2
    7
    20000000
    输出Case 1: 4
    Case 2: 34866117
    数据范围
    对于 100% 的数据, T ≤ 10000, n ≤ 3000000 。
    对于 30% 的数据, n ≤ 5000 。
    对于另外 20% 的数据, T ≤ 10, n ≤ 100000 。


    我们发现a^b=c,a^c=b,而c是a和b的约数,所以我们只需要枚举a和c即可(O(nlogn))。

    再加上求gcd的logn,总复杂度就是O(nlog2n)。

    但是我们a-b<=a^b又gcd(a,b)=c,a-b>=c,所以a-b==c,从而不用求gcd了。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    
    #define ll long long
    #define il inline
    #define db double
    
    using namespace std;
    
    il int gi()
    {
      int x=0,y=1;
      char ch=getchar();
      while(ch<'0'||ch>'9')
        {
          if(ch=='-')
    	y=-1;
          ch=getchar();
        }
      while(ch>='0'&&ch<='9')
        {
          x=x*10+ch-'0';
          ch=getchar();
        }
      return x*y;
    }
    
    il int gcd(int a,int b)
    {
      b!=0?gcd(b,a%b):a;
    }
    
    int ans[3000000];
    
    int main()
    {
      freopen("gcd.in","r",stdin);
      freopen("gcd.out","w",stdout);
      for(int c=1;c<=3000000;c++)
        for(int a=c<<1;a<=3000000;a+=c)
          {
    	int b=a-c;
    	if(c==(a^b))
    	  ans[a]++;
          }
      for(int i=1;i<=3000000;i++)
        ans[i]+=ans[i-1];
      int T=gi();
      for(int i=1;i<=T;i++)
        {
          int n=gi();
          printf("Case %d: %d
    ",i,ans[n]);
        }
      return 0;
    }
    
  • 相关阅读:
    第一章、Docker 简介
    远程库的创建及操作
    分支
    Git常用命令
    初始化本地仓库
    Git的本地结构与远程中心
    Git的安装
    版本控制系统
    冒泡排序
    选择排序
  • 原文地址:https://www.cnblogs.com/gshdyjz/p/9877040.html
Copyright © 2020-2023  润新知