[bzoj2242][Sdoi2011]计算器_exgcd_BSGS

计算器 bzoj-2242 Sdoi-2011

题目大意:裸题,支持快速幂、扩展gcd、拔山盖世

注释:所有数据保证int,10组数据。

想法:裸题,就是注意一下exgcd别敲错... ...

最后,附上丑陋的代码... ...

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
using namespace std;
#define LL long long
map<LL,int> mp;
LL qp(LL x,LL y,LL mod)
{
    LL re=1;
    while(y)
	{
        if(y&1ll)re=re*x%mod;
        x=x*x%mod;
        y>>=1ll;
    }
    return re;
}
void exgcd(LL a,LL b,LL &x,LL &y,LL &p)
{
    if(!b){x=1;y=0;p=a;return ;}
    exgcd(b,a%b,y,x,p);
    y-=(a/b)*x;
}
LL BSGS(LL n,LL a,LL b)
{
    if(n==1)if(!b)return a!=1; else return -1;
    if(b==1)if(a)return 0; else return -1;
    if(a%n==0)if(!b)return 1; else return -1;
    LL m=ceil(sqrt(n)),d=1,base=1;
    mp.clear();
    for(int i=0;i<m;i++)
    {
        if(!mp.count(base))mp[base]=i;
        base=(base*a)%n;
    }
    for(int i=0;i<m;i++)
    {
        LL x,y,s;
        exgcd(d,n,x,y,s);
        x=(x*b%n+n)%n;
        if(mp.count(x))return i*m+mp[x];
        d=(d*base)%n;
    }
    return -1;
}
int main()
{
    int t,k;
    scanf("%d%d",&t,&k);
    int i;
    LL a,b,n,x,y,p;
    for(i=1;i<=t;i++)
	{
        scanf("%lld%lld%lld",&a,&b,&n);
        if(k==1)
		{
            printf("%lld\n",qp(a,b,n));
        }
		else if(k==2)
		{
            exgcd(a,n,x,y,p);
            if(b%p)
			{
                puts("Orz, I cannot find x!");continue;
            }
            x=(x*(b/p)%n+n)%n;
            printf("%lld\n",x);
        }
		else if(k==3)
		{
            LL x=BSGS(n,a,b);
            if(x==-1)puts("Orz, I cannot find x!");
            else printf("%lld\n",x);
        }
    }
}

 

 小结:裸题而已,小结啥...

 

posted @ 2018-07-20 23:11  JZYshuraK_彧  阅读(186)  评论(0编辑  收藏  举报