zoukankan      html  css  js  c++  java
  • 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);
                }
        }
    }
  • 相关阅读:
    lombok自定义扩展实践
    Java8新特性之重复注解(repeating annotations)
    PowerMockito单元测试中的Invalid use of argument matchers问题详解
    sublimerge
    springboot Properties加载顺序源码分析
    关于U盘启动操作系统《30天自制操作系统》
    操作系统学习基本概念汇总
    使用图灵机器人高速开发智能聊天机器人
    LeetCode89:Gray Code
    Android Studio开发Android问题集【持续更新】
  • 原文地址:https://www.cnblogs.com/yfceshi/p/7039943.html
Copyright © 2011-2022 走看看