[BZOJ2242][SDOI2011]计算器

来源:互联网 发布:心理学电脑软件 编辑:程序博客网 时间:2024/06/08 13:22

原题地址

复习了一下离散对数.

偷懒用map,结果差点就T了囧,这个故事再次告诉我们尽量不要用map!

AC code:

#include <cstdio>#include <cmath>#include <map>using namespace std;typedef long long ll;ll t,k,y,z,p;ll work1(ll y,ll q){    if(!q) return 1;    ll x=work1(y,q>>1);    x=(x*x)%p;    if(q&1) x=(x*y)%p;    return x;}ll work2(){    return z*work1(y,p-2)%p;}void work3(){    if(!(y%p)){        printf("Orz, I cannot find x!\n");        return ;    }    ll m=(ll)sqrt(p),inv=work1(work1(y,m),p-2),tz=z%p;    map<ll,bool> H;    map<ll,ll> ind;    for(ll i=0;i<m;i++){        H[work1(y,i)]=1;        ind[work1(y,i)]=i;    }    for(ll i=0;i<=m;i++){        if(i) tz=(tz*inv)%p;        if(H[tz]){            printf("%lld\n",i*m+ind[tz]);            return ;        }    }    printf("Orz, I cannot find x!\n");}int main(){    scanf("%lld%lld",&t,&k);    while(t--){        scanf("%lld%lld%lld",&y,&z,&p);        if(k==1) printf("%lld\n",work1(y,z));        else if(k==2){            if(!(y%p)){                printf("Orz, I cannot find x!\n");                continue;            }            printf("%lld\n",work2());        }        else work3();    }    return 0;}
0 0