UVA 12716 GCD XOR

题目要求找到所有小于等于n的整数对(a, b),满足a > b,且a与b的最大公约数的异或值等于a与b的乘积。通过观察,发现当a与b的公约数为c时,a可以表示为c的倍数,b则可以通过a异或c得到。进一步分析,如果b满足条件axorb=gac(a,b),那么b一定等于a减去gcd(a,b)。因此,可以枚举a、c,计算出b,并验证gcd(a,b)是否为c以及a^b是否等于c。算法的时间复杂度为O(nlogn)。" 88381881,4832771,理解nginx的信号机制,"['nginx源码分析', '进程通信', '信号处理']
摘要由CSDN通过智能技术生成

题意:求小于等于n的(a,b) 满足 a>b且 axorb=gac(a,b)的所以(a,b)数目 

n有30000000这么大  所以一直在想什么O(1)的算法 然而后来才发现 T放宽到5秒 还不限内存 Orz

设c为gcd(a,b) 而亦或的特性是 满足a^b=c 则 a^c=b。

所以我们可以枚举c 而a是c的倍数 所以可以再枚举a 再算出b=a^c 再检查是否满足 gcd(a,b)==c

而这题还有一个神奇的特性 即 若b满足 axorb=gac(a,b) 则 b一定为 a-gcd(a,b)

这样我们枚举出a,c 的时候 b=a-c 而这时gcd(a,b)是一定为c的  (原因同辗转相减法) 只需验证 是否a^b==c

时间复杂度O(nlogn)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cctype>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<algorithm>
#include<set>
#define scnaf scanf
#define cahr char
#define bug puts("bugbugbug");
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int mod=1000000007;
const int maxn=3e7+10;
const int inf=1e9;
int ans[maxn];
int main()
{
    for(int n
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值