hdu6641TDL(19年杭電第六場多校賽第8題)

TDL
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 0 Accepted Submission(s): 0

Problem Description
For a positive integer n, let’s denote function f(n,m) as the m-th smallest integer x that x>n and gcd(x,n)=1. For example, f(5,1)=6 and f(5,5)=11.

You are given the value of m and (f(n,m)−n)⊕n, where ``⊕’’ denotes the bitwise XOR operation. Please write a program to find the smallest positive integer n that (f(n,m)−n)⊕n=k, or determine it is impossible.

Input
The first line of the input contains an integer T(1≤T≤10), denoting the number of test cases.

In each test case, there are two integers k,m(1≤k≤1018,1≤m≤100).

Output
For each test case, print a single line containing an integer, denoting the smallest n. If there is no solution, output ``-1’’ instead.

Sample Input
2
3 5
6 100

Sample Output
5
-1
題意: 給出f(n,m),即爲大於n的第m個與n互質的數,給出k和m,找出最小的n使其滿足(f(n,m)-n) ^ n = k。
思路: 要使其異或結果爲k,則n與另一個數的二進制位數一定是和k的二進制位數相同,又m小於100,打表可發現第m個與n互質的數的差值不超過1000,所以枚舉k的左邊界和右邊界區域即可,如果k小於等於1000,其左邊界從1開始,否則從k-1000開始,右邊界爲k+1000。詳情看代碼。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll f(ll x, ll m) { // 找出從x+1開始第m個與x的最大公約數爲1的數 
	ll k = 0, ans;
	for (ll i = x + 1; ; i++) {
		if (__gcd(i, x) == 1) {
			k++;
			ans = i;
		}
		if (k == m) {
			return ans;
		}
	}
}

int main() {
	int t;
	scanf("%d", &t);
	while (t--) {
		ll k, m;
		scanf("%lld%lld", &k, &m);
		if (k == m) { 
			// k和m相同時直接輸出-1,因爲此時的n的二進制位數一定大於k的位數 
			printf("-1\n");
			continue;
		}
		ll tt;
		if (k < 1001) tt = 1; // 確定解的左邊界 
		else tt = k - 1000;
		ll flag = 0;
		for (ll i = tt; i < k + 1000; i++) {
			if ((f(i, m) - i) == (k ^ i)) {
				flag = i;
				break;
			}
		}
		if (!flag) {
			printf("-1\n");
		} else {
			printf("%lld\n", flag);
		}
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章