BZOJ 2242 [SDOI2011]计算器 BSGS+快速幂+EXGCD

来源:互联网 发布:可视化编程 编辑:程序博客网 时间:2024/04/30 18:30

题意:链接

方法: BSGS+快速幂+EXGCD

解析:

BSGS…

题解同上..

代码:

#include <cmath>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define MOD 140345using namespace std;typedef long long ll;ll t,k,ans;ll y,z,p;int head[MOD+10],cnt;struct node{    ll from,to,val,next;}edge[MOD+10];void init(){    memset(head,-1,sizeof(head));    cnt=1;}void edgeadd(ll from,ll to,ll val){    edge[cnt].from=from,edge[cnt].to=to,edge[cnt].val=val;    edge[cnt].next=head[from];    head[from]=cnt++;}ll quick_my(ll x,ll y){    ll ret=1;    while(y)    {        if(y&1)ret=(ret*x)%p;        x=(x*x)%p;        y>>=1;    }    return ret;}void exgcd(ll a,ll b,ll &x,ll &y,ll &gcd){    if(!b)    {        x=1,y=0,gcd=a;        return;    }    exgcd(b,a%b,y,x,gcd);    y=y-a/b*x;}void BSGS(ll A,ll B,ll C){    //A^x=B(mod C)    ll m=(int)ceil(sqrt(C));    ll k=1;    for(int i=0;i<m;i++)    {        int flag=1;        for(int j=head[k%MOD];j!=-1;j=edge[j].next)        {            if(edge[j].val==k){flag=0;continue;}        }        if(flag)edgeadd(k%MOD,i,k);        k=k*A%C;    }    ll X,Y,GCD;    exgcd(k,C,X,Y,GCD);    ll invk=(X%C+C)%C;    ll D=1,invD=1;    for(int i=0;i<=m;i++)    {        ll tmpB=B*invD%C;        for(int j=head[tmpB%MOD];j!=-1;j=edge[j].next)        {            if(edge[j].val==tmpB){ans=i*m+edge[j].to;return;}        }        D=D*k%C;        invD=invD*invk%C;    }}int main(){    scanf("%lld%lld",&t,&k);    switch(k)    {        case 1:            while(t--)            {                scanf("%lld%lld%lld",&y,&z,&p);                printf("%lld\n",quick_my(y,z));            }            break;        case 2:            while(t--)            {                ll x,tmp,gcd;                scanf("%lld%lld%lld",&y,&z,&p);                exgcd(y,p,x,tmp,gcd);                if(z%gcd!=0)puts("Orz, I cannot find x!");                else                {                    ll mod=p/gcd;                    printf("%lld\n",((x*z/gcd)%mod+mod)%mod);                }            }            break;        case 3:            while(t--)            {                init();                scanf("%lld%lld%lld",&y,&z,&p);                ans=-1;                if(y%p==0&&z!=0){puts("Orz, I cannot find x!");continue;}                BSGS(y,z,p);                if(ans==-1)puts("Orz, I cannot find x!");                else printf("%lld\n",ans);            }    }}
0 0
原创粉丝点击