[51nod 1479]小Y的数论题

来源:互联网 发布:同志软件哪个最好 编辑:程序博客网 时间:2024/06/10 08:47

题目描述

小Y喜欢研究数论,并且喜欢提一些奇怪的问题。
这天他找了三个两两互质的数a, b, c,以及另一个数m, 现在他希望找到三个(0, m)范围内的整数x, y, z,使得
(x^a+y^b) Mod m=(z^c) Mod m

构造

我们知道2^x+2^x=2^(x+1)
于是我们这样构造:
若m不为2的幂数,我们令x=2^kb,y=2^ka,z=2^l,那么cl-kab=1,可以用扩展欧几里得求解。
否则,更容易构造,讨论a、b、c是否大于1,然后均为1也容易构造,详见代码。

#include<cstdio>#include<algorithm>#define fo(i,a,b) for(i=a;i<=b;i++)using namespace std;typedef long long ll;ll a,b,c,x,y,z,m,l,k,xx,yy,t,ca;void gcd(ll a,ll b){    if (!b){        xx=1;        yy=0;        return;    }    else{        ll x,y;        gcd(b,a%b);        x=yy;        y=xx-(a/b)*yy;        xx=x;yy=y;     }}ll quicksortmi(ll x,ll y,ll mo){    if (!y) return 1;    ll t=quicksortmi(x,y/2,mo);    t=t*t%mo;    if (y%2) t=t*x%mo;    return t;}int main(){    scanf("%lld",&ca);    while (ca--){        scanf("%lld%lld%lld%lld",&m,&a,&b,&c);        t=m;        while (t%2==0) t/=2;        if (t==1){            if (a>1){                x=m/2;                y=z=1;            }            else if (b>1){                y=m/2;                x=z=1;            }            else if (c>1) x=y=z=m/2;            else{                x=y=1;                z=2;            }        }        else{            gcd(c,a*b);            l=xx;k=yy;            while (l<0||k>0){                l+=a*b;                k-=c;            }            z=quicksortmi(2,l,m);            x=quicksortmi(2,k*b,m);            y=quicksortmi(2,k*a,m);        }        printf("%lld %lld %lld\n",x,y,z);    }}
0 0
原创粉丝点击