HDU 6624 fraction【數論】

題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=6624
題目大意:給定p,xp,x,存在兩整數a,ba,b,求解滿足a<b, abx(mod p)a<b,\ a≡bx(mod \ p)的最小值bb

思路:
a=bxcpa=bx-cp,則存在不等式0bxcpb0\le{bx-cp}\le{b}
變換一下得到:px<bc<px1\frac{p}{x}\lt{\frac{b}{c}\lt{\frac{p}{x-1}}},我們要解出這個不等式中的min(b)min(b)值。
這時候可以想到運用類似於輾轉相除法的形式來解決這個問題:
(1)令z1=px, z2=px1z_1=\lfloor\frac{p}{x}\rfloor,\ z_2=\lfloor\frac{p}{x-1}\rfloor
(2)如果z1!=z2z_1!=z_2,則令c=1,b=z1+1c=1,b=z_1+1(因爲不含等號,所以要加1)跳出循環。否則就執行(3)。
(3)不等式同步減掉z1z_1,不等式變爲:pz1xx<bz1cc<pz1(x1)x1\frac{p-z_1*x}{x}\lt{\frac{b-z_1*c}{c}\lt{\frac{p-z_1*(x-1)}{x-1}}},分子分母翻轉一下得到:x1pz1(x1)<cbz1c<xpz1x\frac{x-1}{p-z_1*(x-1)}\lt{\frac{c}{b-z_1*c}\lt{\frac{x}{p-z_1*x}}},這個式子和最初得到的原式(px<bc<px1)(\frac{p}{x}\lt{\frac{b}{c}\lt{\frac{p}{x-1}}})是不是有點相像,兩式對應一下遞歸就okok了。

證明:算法正確性菜雞無法證明,很像輾轉相除法。
AC代碼:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll p,xx;
ll b,c;
void solve(ll p,ll x,ll &b,ll &c,ll pp,ll y)//y=x-1
{
    ll z1=p/x;
    ll z2=pp/y;
    if(z1!=z2){
       c=1;
       b=z1+1;//因爲不等式不帶等號
       return ;
    }
    p-=z1*x;
    pp-=z1*y;
    b-=c*z1;
    solve(y,pp,c,b,x,p);
    b+=c*z1;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
       scanf("%lld%lld",&p,&xx);
       b=0;
       c=0;
       solve(p,xx,b,c,p,xx-1);//按照不等式從左到右依次傳參
       ll a=b*xx-c*p;
       printf("%lld/%lld\n",a,b);
    }
    return 0;
}
/*
3
11 7
998244353 554580197
998244353 998244352

2/5
8/9
499122176/499122177
*/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章