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 nthat (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 100Sample Output
5
-1
题意:t 组数据,函数 f(n,m) 表示比 n 大的第 m 小的与 m 互质的数,现在每组给出 k、m 两个数,对于式子 (f(n,m)-n)⊕n=k,求最小的 n,如果没有答案,输出 -1
思路:
对于 (f(n,m)-n)⊕n=k
设 d=f(n,m)-n
那么根据异或的性质,有:d=n⊕k
故而:n=d⊕k
根据质数分布密度定理:素数的分布越来越稀疏,当 1E18 内的任意两个素数的差不会很大(不会超过 300),因此可以直接枚举 d 的值来寻找答案
Source Program
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<unordered_map>
#include<bitset>
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LL long long
#define Pair pair<int,int>
LL quickPow(LL a,LL b){ LL res=1; while(b){if(b&1)res*=a; a*=a; b>>=1;} return res; }
LL multMod(LL a,LL b,LL mod){ a%=mod; b%=mod; LL res=0; while(b){if(b&1)res=(res+a)%mod; a=(a<<=1)%mod; b>>=1; } return res%mod;}
LL quickPowMod(LL a, LL b,LL mod){ LL res=1,k=a; while(b){if((b&1))res=multMod(res,k,mod)%mod; k=multMod(k,k,mod)%mod; b>>=1;} return res%mod;}
LL getInv(LL a,LL mod){ return quickPowMod(a,mod-2,mod); }
LL GCD(LL x,LL y){ return !y?x:GCD(y,x%y); }
LL LCM(LL x,LL y){ return x/GCD(x,y)*y; }
const double EPS = 1E-10;
const int MOD = 998244353;
const int N = 1000+5;
const int dx[] = {-1,1,0,0,1,-1,1,1};
const int dy[] = {0,0,-1,1,-1,1,-1,1};
using namespace std;
LL cal(LL n, int m) {
if (n < 1)
return 0;
else{
LL i=n+1;
while(true){
if (GCD(n, i) == 1) {
m--;
if (!m)
return i - n;
}
i++;
}
}
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
LL k;
int m;
scanf("%lld%d", &k, &m);
LL res = -1;
for (int d = 1; d <= 1000; d++) {
if (cal(k ^ d, m) == d) {
if (res == -1)
res = k ^ d;
else if (res > (k ^ d))
res = k ^ d;
}
}
printf("%lld\n", res);
}
return 0;
}