fraction(HDU-6624)
Problem Description
Many problems require printing the probability of something. Moreover, it is common that if the answer is a/b, you should output a×b^(−1)(modp) (p is a prime number). In these problems, you cannot know the exact value of the probability. It's so confusing!!! Now, we want to reverse engineer the exact probability from such calculated output value x. We do so by guessing the probability is the one with the minimum b such that a×b^(−1)=x(modp). Now we invite you to solve this problem with us!
You are given two positive integers p and x, where p is a prime number.
Please find the smallest positive integer b such that there exist some positive integer a satisfying a<b and a≡bx(modp).
Input
The first line contains an integer T indicating there are T tests. Each test consists of a single line containing two integers: p,x.
* 1≤T≤2×105
* 3≤p≤1015
* p is a prime
* 1<x<p
Output
For each test, output a line containing a string represents the fraction a/b using the format "a/b" (without quotes).
Sample Input
3
11 7
998244353 554580197
998244353 998244352Sample Output
2/5
8/9
499122176/499122177
题意:t 组数据,每组给出 p、x 两个数,要求找出最小正整数的 b ,使得正整数 a<b 且满足 a=bx(mod p),要求最后输出 a/b 的最简形式
思路:
本题除了给出的 a=bx(mod p) 条件外,还给出了一个隐含的条件:0<a<b
利用给出的这个不等关系,将 a=bx(mod p) 写成函数的形式,即:bx=py+a,那么有:a=bx-py
代入不等式有:0<bx-py<b
展开:
即:
同除以 b 得:
同除以 p 得:
取倒数有:
因此,为求出最小的 b,可以不断进行迭代来求
由于 p>x,因此 ,减去其整数部分,即设
则有:
取倒数:
继续减去左边的整数部分,可以得出 不断减小,故而只需要不断进行迭代,当
时,终止迭代,此时 b 的值即为迭代过程中的 t,然后再根据 b 来计算 a 即可得出答案
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 = 10000+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;
void dfs(LL a, LL b, LL c, LL d, LL &x, LL &y) {
LL t = (a + b - 1) / b; //减去整数部分的t
if (c / d >= t) {
x = t;
y = 1;
return;
}
//迭代后的新值
a = a - (t - 1) * b;
c = c - (t - 1) * d;
//新一轮迭代
dfs(d, c, b, a, y, x);
//更新b
x = x + (t - 1) * y;
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
LL p, x;
scanf("%lld%lld", &p, &x);
LL b, y;
dfs(p, x, p, x - 1, b, y);
LL a = b * x - p * y;
printf("%lld/%lld\n", a, b);
}
return 0;
}