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