BZOJ 2242 计算器

Posted on 2016-10-11 18:00  ziliuziliu  阅读(113)  评论(0编辑  收藏  举报

该模的要模,该特判的要特判。。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<cmath>
using namespace std;
map <long long,long long> mp;
long long t,k,y,z,p,x,q;
long long f_pow(long long y,long long z,long long p)
{
    long long ans=1,base=y;
    while (z)
    {
        if (z&1) ans=(ans*base)%p;
        base=(base*base)%p;
        z>>=1;
    }
    return ans;
}
long long exgcd(long long a,long long b,long long &x,long long &y)
{
    if (b==0)
    {
        x=1;y=0;
        return a;
    }
    long long d=exgcd(b,a%b,x,y);
    long long t=x;
    x=y;y=t-(a/b)*y;
    return d;
}
long long BSGS(long long y,long long z,long long p)
{
    mp.clear();
    if (z==1) return 0;
    long long m=(long long)(sqrt(1.0*p)+1);long long base=z;
    for (long long i=0;i<m;i++)
    {
        mp[base]=i;
        base=(base*y)%p;
    }
    base=f_pow(y,m,p);long long now=base;
    for (long long i=1;i<=m+1;i++)
    {
        if (mp.count(now)) return i*m-mp[now];    
        now=(now*base)%p;
    }
    return -1;
}
void work1()
{
    for (long long i=1;i<=t;i++)
    {
        scanf("%lld%lld%lld",&y,&z,&p);y%=p;
        printf("%lld\n",f_pow(y,z,p));
    }
}
void work2()
{
    for (long long i=1;i<=t;i++)
    {
        scanf("%lld%lld%lld",&y,&z,&p);y%=p;z%=p;
        long long d=exgcd(y,p,x,q);
        if (z%d) printf("Orz, I cannot find x!\n");
        else
        {
            x*=(z/d);x%=p; 
            while (x<0)
                x+=p;
            printf("%lld\n",x);    
        }
    }
}
void work3()
{
    for (long long i=1;i<=t;i++)
    {
        scanf("%lld%lld%lld",&y,&z,&p);
        y%=p;z%=p;
        if (!y)
        {
            if (!z) printf("1\n");
            else printf("Orz, I cannot find x!\n");
            continue;
        }
        long long d=BSGS(y,z,p);
        if (d==-1) printf("Orz, I cannot find x!\n");
        else printf("%lld\n",d%p);
    }
}
int main()
{
    scanf("%lld%lld",&t,&k);
    if (k==1) work1();
    else if (k==2) work2();
    else work3();
    return 0;
}