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


    题意:链接

    方法: BSGS+高速幂+EXGCD

    解析:

    BSGS…

    题解同上..

    代码:

    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define MOD 140345
    using 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
    ",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
    ",((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
    ",ans);
                }
        }
    }
  • 相关阅读:
    C#使用System.IO.Path获取文件路径、文件名
    C# 中的await
    深度学习笔记
    单例模式
    hbase的写和读,大合并和小合并
    自定义kafka Sink
    combineByKey
    spark练习题
    sparkonhbase
    HDFS只支持文件append操作, 而依赖HDFS的HBase如何完成增删改查功能
  • 原文地址:https://www.cnblogs.com/yfceshi/p/7039943.html
Copyright © 2020-2023  润新知