【bzoj2242】【SDOI2011】计算器

来源:互联网 发布:python黑客教程 编辑:程序博客网 时间:2024/05/29 09:49

= =这道三合一的水题,第一问快速幂,第二问exgcd,第三问BSGS,然后代码很容易写,其实也蛮长的QAQ

#include<cstdio>#include<iostream>#include<cstring>#include<string>#include<algorithm>#include<map>#include<cmath>using namespace std;typedef long long ll;ll p;map<ll,ll>hs;inline ll fpow(ll a,ll b){    ll ans=1;    for (;b;b>>=1,a=a*a%p)    if (b&1)ans=ans*a%p;    return ans;}inline ll exgcd(ll a,ll b,ll &x,ll &y){    if (b==0)    {        x=1;        y=0;        return a;    }    int q=exgcd(b,a%b,x,y);    int tmp=x;    x=y;    y=tmp-a/b*y;    return q;}inline ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}void solve2(ll y,ll z){    ll q=gcd(y,p);    if (z%q!=0){printf("Orz, I cannot find x!\n");return;}    ll x,k;    exgcd(y,p,x,k);    x*=(z/q);    q=y*p/q/y;    x=((x%q)+q)%q;    printf("%lld\n",x);}inline void bsgs(ll y,ll z){    if (y%p==0){printf("Orz, I cannot find x!\n");return;}    int pd=0;    hs.clear();    ll m,y_m,mul,now,ans;    m=ceil(sqrt(p));    mul=1;    hs[mul*z%p]=0;    for (int i=1;i<=m;i++)    {        mul=mul*y%p;        now=mul*z%p;        hs[now]=i;    }    y_m=fpow(y,m);    mul=1;    for (int i=1;i<=m;i++)    {        mul=mul*y_m%p;        if (hs[mul])        {            pd=1;            ans=m*i-hs[mul];            printf("%lld\n",ans);            break;        }    }    if (!pd){printf("Orz, I cannot find x!\n");}}int main(){//  freopen("std.out","w",stdout);    int n,k;    cin>>n>>k;    if (k==1)    {        while (n--)        {            ll y,z;            scanf("%lld%lld%lld",&y,&z,&p);            printf("%lld\n",fpow(y,z));        }    }    else     if (k==2)    {        while(n--)        {            ll y,z;            scanf("%lld%lld%lld",&y,&z,&p);            solve2(y,z);        }    }    else     {        while(n--)        {            ll y,z;            scanf("%lld%lld%lld",&y,&z,&p);            bsgs(y,z);        }    }    return 0;}
0 0
原创粉丝点击