当前位置: 代码迷 >> 综合 >> 紫书 例题 10-5 UVa 12716 (枚举方式)
  详细解决方案

紫书 例题 10-5 UVa 12716 (枚举方式)

热度:110   发布时间:2023-09-20 21:07:05.0

设gcd(a, b) = a xor b = c

那么我们可以证明c=a-b

那么同时c又是a的因子(c是a与b的最大公因数)

所以我们可以枚举c,然后枚举c的倍数,也就是a

有了a和c可以算出b为a-c

然后最后验算是否a xor b = c就ok了。

这里的枚举方式非常的巧妙,是反过来枚举c

来推a,如果枚举a的因子c的话就会很耗时间了。

#include<cstdio>
#include<cmath>
#define REP(i, a, b) for(int i = (a); i < (b); i++)
using namespace std;const int MAXN = 30000001;
int cnt[MAXN], sum[MAXN];void init()
{REP(c, 1, MAXN)for(int a = c * 2; a < MAXN; a += c)if(c == (a ^ (a - c))) cnt[a]++;REP(i, 1, MAXN) sum[i] = sum[i-1] + cnt[i];
}int main()
{init();int T, kase = 0, n;scanf("%d", &T);while(T--){scanf("%d", &n);printf("Case %d: %d\n", ++kase, sum[n]);}return 0;
}