UVA12716 GCD XOR 数论数学构造

题目给你一个N,让你求 两个数字 A,B,且   A>=B<=N,是的 gcd(A,B) == A^B

N的范围是 3*10^7大的吓人一开始没敢想构造,因为就算构造开的数组也太大了,已经10^7了,后来想了半天在^运算这里也没有想出来什么,所以没办法还是大胆构造吧,构造就去按照他题目的意思来了,构造两个数字 i,j其中j是i的倍数,那么j + i与i的最大公约数肯定是i了,那么(j+i)^i == i这样构造出来的就算满足了,然后再模仿gcd辗转相除的愿意  把它们放在一个数组里计数,这样预处理即可

打好以后又打了一个暴力程序来跑答案,结果都是对的,但是交了超时,因为一开始预处理都给赋值了 long long型,在辗转相除的时候 有个%运算,会导致很慢,所以改成int就对了

#define  _CRT_SECURE_NO_WARNINGS
/*#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<string>
#include<math.h>
using namespace std;

#define IN freopen("c:\\Users\\nit\\desktop\\input.txt", "r", stdin)
#define OUT freopen("c:\\Users\\nit\\desktop\\output.txt", "w", stdout)   

int gcd(int a,int b)
{
	return b==0?a:gcd(b,a%b);
}
int main()
{
	OUT;
	int ans[510],k=0;
	memset(ans,0,sizeof(ans));
	for(int i=1;i<500;i++)
	{
		for(int b=1;b<=i;b++)
		{
			for(int a=b;a<=i;a++)
			{
				if((a^b)==gcd(a,b))
					ans[i]++;
			}
		}
		printf("%d\t",ans[i]);
		if(k%10==0)puts("");
		k++;
	}
	return 0;
}*/

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<string>
#include<math.h>
using namespace std;

//#define IN freopen("c:\\Users\\nit\\desktop\\input.txt", "r", stdin)
//#define OUT freopen("c:\\Users\\nit\\desktop\\outpu1t.txt", "w", stdout)   

#define ll long long

#define MAXN 30000000 + 5

ll ans[MAXN];

void init() {
	for(ll i = 1;i<MAXN;i++) {
		for(ll j = i;i + j < MAXN;j += i) {
			if( ((i + j)^j) == i) {
				int x = j;
				int y = i + j;
				for(;x > 0 && y > 0;) {
					int tmp = x%y;
					x = y;
					y = tmp;
					if((x + y) == i)
						ans[i + j]++;
				}
			}
		}
	}
	for(int i = 2;i<MAXN;i++)
		ans[i] += ans[i-1];
}

int main() {
	init();
	int t;
	scanf("%d",&t);
	int	 Case = 0;
	while(t--) {
		int n;
		scanf("%d",&n);
		printf("Case %d: %lld\n",++Case,ans[n]);
	}
	return 0;
}

UVA12716 GCD XOR 数论数学构造

时间: 2024-08-10 17:11:48

UVA12716 GCD XOR 数论数学构造的相关文章

UVA-12716 - GCD XOR

[思路]a^b = c等价于a^c = b  所以枚举a和c,而a和c全部枚举肯定TLE,所以高效算法:通过c是a的约数这个关系来枚举会减小循环,必须要将c放在循环外面,因为c的情况比较少.其实本题就是要求:c=a-b(规律),c=a^b 以下是高神的AC代码,很好很强大: #include <cstdio> #include <iostream> #include <cmath> #include <string> using namespace std;

UVA12716 GCD XOR(枚举)

UVA12716 GCD XOR Description Given an integer N, find how many pairs (A, B) are there such that: gcd(A, B) = A xor B where 1 ≤ B ≤ A ≤ N. Here gcd(A, B) means the greatest common divisor of the numbers A and B. And A xor B is the value of the bitwise

UVA 12716 GCD XOR(数论+枚举+打表)

 题意:给你一个N,让你求有多少组A,B,  满足1<= B <= A <= N, 且 gcd(A,B) = A XOR B. 思路:首先我们可以得出两个结论: A-B >= A%B >= gcd(A, B) A xor B >= A-B 所以说A xor B >= A-B >= gcd(A, B),然后就可以推出 A xor B = A - B = gcd(A, B) =>    A xor B = A - B  &&  A -

uva12716 GCD XOR(打表找规律+筛法)

题意:输入整数(1=<n<=30000000),有多少对整数(a,b)满足:1=<b=<a=<n,且gcd(a,b)=a^b.例如n=7时,有4对:(3,2),(5,4),(6,4),(7,6) 解题思路: 看到题目之后一直在找最大公约数和异或之间的关系,但找了半天没有发现.于是果断打表发现如下规律 满足gcd(a,b)=a^b的数有如下规律,要么就是a=b-1,要么就是有前面已求得的满足条件的乘上一定的倍数得到如下: 根据上述规律,我们便可以求的所有的可能性,上面只打印了一

[UVA-12716] GCD XOR 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接(vjudge):https://vjudge.net/problem/UVA-12716 题目大意: 输入一个数字t,表示数据组数. 接下来t行,每行给出一个整数n(1<=n<=30000000),问有多少对整数a,b(1<=b<=a<=n),满足gcd(a,b) = a^b. 对于每个n,输出Case x: y,表示当前是第x组数据,结果是y. Sample Input 2 7 20000000

UVa12716 - GCD XOR

题意 给一个数n,找出gcd(a,b) = a^b的个数   (1<=b<=a<=n). n的数据范围:1到30000000 思路 c满足gcd(a,b) = a^b,打表观察数据得出c = a - b:又因为c是a的约数,用类似素数筛选的方法降低时间复杂度. 总结 敲代码的时候忘记打表这个东西的存在,只要一次性将所有的结果算出存在数组里,每次提取就可以,不用每次都算一遍. 智障啊_(:з」∠)_为什么想不到,不然又可以A一道题 #include <iostream> #in

UVa 12716 &amp;&amp; UVaLive 6657 GCD XOR (数论)

题意:给定一个 n ,让你求有多少对整数 (a, b) 1 <= b <= a 且 gcd(a, b) = a ^ b. 析:设 c = a ^ b 那么 c 就是 a 的约数,那么根据异或的性质 b = a ^ c,那么我们就可以枚举 a 和 c和素数筛选一样,加上gcd, n*logn*logn. 多写几个你会发现 c = a - b,证明如下: 首先 a - b <= a ^ b,且 a - b >= c,下面等于等号,用反证法,假设存在 a - b > c,那么 c

数论&amp;数学

数论&数学从入门到放弃 组合数学 →组合数学常用公式 组合数: 将n个不同的球放入m个相同的盒子里的方案数 (从 n 个不同元素中每次取出 m 个不同元素,不管其顺序合成一组,称为从 n 个元素中不重复地选取 m 个元素的一个组合.所有这样的组合的种数称为组合数.) 递推公式:C(n,m)= C(n - 1,m - 1)+ C(n - 1,m) (其它计算公式见组合数学常用公式) 推导方法: 若新的球独占一个盒子,则其它球占 m - 1 个盒子,共有 C(n - 1,m - 1)种方案 若新的球

【Math】GCD XOR 证明

题目:Given an integer N, and how many pairs (A;B) are there such that: gcd(A;B) = A xor B where 1<=B<=A<=N. 首先先爆一发,妥妥超时.其实真相是我想打表找规律.结果没什么规律可循. 后来分析:要想让GCD(A,B)==(A^B),A和B一定是同样的位数(二进制).因此打表方法可变为:(亦超时) void init() { int K=0; int last=0; for(int i=1;