uvaoj 12716 GCD XOR 打表

16 篇文章 0 订阅
uvaoj 12716 GCD XOR 打表
输入整数n(1<=n<=30000000),有多少整数对(a,b)满足1<=b<=a<=n,且gcd(a,b)=a^b=c。当n=7时,有4对,(3,2),(5,4),(6,4),(7,6).
对于异或运算,有a^b^b=a,所以可以推出,若a^b=c,则a^c=b,可以枚举a和c,算出b,验证是否有gcd(a,b)=c,注意到c是a的约数,所以,可以使用素数筛法的方法,复杂度为nlogn。
进一步可以发现,c=a-b,因为a-b<=a^b,且a-b>=c,假设存在c使得a-b>c,那么c<a-b<=a^b,这与c=a^b矛盾。
代码如下:
/*************************************************************************
	> File Name: 12716.cpp
	> Author: gwq
	> Mail: gwq5210@qq.com 
	> Created Time: 2015年01月21日 星期三 21时30分29秒
 ************************************************************************/

#include <cmath>
#include <ctime>
#include <cctype>
#include <climits>
#include <cstdio>
#include <cstdlib>
#include <cstring>

#include <map>
#include <set>
#include <queue>
#include <stack>
#include <string>
#include <vector>
#include <sstream>
#include <iostream>
#include <algorithm>

#define INF (INT_MAX / 10)
#define clr(arr, val) memset(arr, val, sizeof(arr))
#define pb push_back
#define sz(a) ((int)(a).size())

using namespace std;
typedef set<int> si;
typedef vector<int> vi;
typedef map<int, int> mii;
typedef long long ll;
typedef unsigned long long ull;

const double esp = 1e-5;

#define N 30000010

int ans[N];

int main(int argc, char *argv[])
{
	int t;
	int cnt = 0;
	scanf("%d", &t);
	for (ll c = 1; c <= N / 2; ++c) {
		for (ll a = c * 2; a <= N; a += c) {
			int b = a - c;
			if ((a ^ b) == c) {
				++ans[a];
			}
		}
	}
	for (ll c = 1; c < N; ++c) {
		ans[c] += ans[c - 1];
	}
	while (t--) {
		int n;
		scanf("%d", &n);
		printf("Case %d: %d\n", ++cnt, ans[n]);
	}

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值