博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
「NOIP2018模拟9.10」公约数 - 找规律 - gcd
阅读量:4550 次
发布时间:2019-06-08

本文共 1163 字,大约阅读时间需要 3 分钟。

公约数


Time Limits: 1000 ms

Memory Limits: 262144 KB
Detailed Limits


Description

给定一个正整数\(n\),在\([1,n]\)的范围内,求出有多少个无序数对\((a,b)\)满足\(gcd(a,b) = a\) \(xor\) \(b\)

Input

输入共一行,一个正整数\(n\)

Output

输出共一行,一个正整数表示答案。

Sample Input

3

Sample Output

1

Data Constraint

对于\(30\)%的数据满足\(n\leq1000\)

对于\(60\)%的数据满足\(n\leq1\times10^{5}\)
对于\(100\)%的数据满足\(n\leq1\times10^{7}\)

Hint

只有\((2,3)\)满足要求。

分析

我在打表的时候得出一个结论:满足条件的\(gcd(a,b) = a\)^\(b = a-b\) (设\(a\)为较大数)

此时\(a\)\(b\)都是\(a-b\)也就是\(gcd(a,b)\)的倍数
我们用\(i\)枚举\(a-b\),用\(j\)枚举\(a\),此时\(j\)始终为\(i\)的倍数
这时\(a=j\)\(b=j-i\)
那么\(a\)^\(b = a-b\)就等价于\(j\)^\((j-i) = i\)
枚举即可 复杂度\(O(nlogn)\)

代码

#include
#include
#define rg register#define int long long using namespace std;inline int read(){ rg int f=0,x=0; rg char ch=getchar(); while(!isdigit(ch)) f|=(ch=='-'),ch=getchar(); while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); return f?-x:x;}int n,ans;signed main() { n=read(); for(rg int i=1;i<=n;++i)//枚举(a-b) for(rg int j=(i<<1);j<=n;j+=i)//枚举 a ans+=((j^(j-i))==i); printf("%lld",ans); return 0;}

转载于:https://www.cnblogs.com/horrigue/p/9622019.html

你可能感兴趣的文章
BZOJ 1854 【SCOI2010】 游戏
查看>>
JavaScript - 匿名函数和闭包
查看>>
负载均衡下的资源文件配置/多站点下的资源文件夹共享(Windows IIS)
查看>>
MySQL firstmatch strategy
查看>>
MS SQL server 2014 创建用户及权限
查看>>
office很抱歉遇到一些临时服务器问题
查看>>
禁止键盘上的刷新键F5等
查看>>
SAP中对于获取订单的状态
查看>>
oracle PL/SQL块
查看>>
sklearn.preprocessing.LabelBinarizer
查看>>
C teaching
查看>>
分隔指定内容,提取章节数
查看>>
this point
查看>>
leetcode 30 Substring with Concatenation of All Words
查看>>
验证登录信息是否合法
查看>>
线程池
查看>>
git版本控制器的基本使用
查看>>
Redis 笔记与总结4 set 和 zset 类型
查看>>
jQuery Ajax 回调函数中调用$(this)的问题 [ 转 ]
查看>>
thymeleaf:字符串拼接+输出单引号
查看>>