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;
}