[SDOI2011] 计算器

题目链接:戳我

三合一??
第一问是。。快速幂。
第二问求逆元。最后乘上z即可。
第三问bsgs模板了。
bsgs不会?戳我

代码如下:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
using namespace std;
int t,k,y,z,p;
map<int,int>M;
inline int pow(int x,int y)
{
    int cur_ans=1;
    while(y)
    {
        if(y&1) cur_ans=(1ll*cur_ans*x)%p;
        x=(1ll*x*x)%p;
        y>>=1;
    }
    return cur_ans%p;
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d%d",&t,&k);
    while(t--)
    {
        scanf("%d%d%d",&y,&z,&p);
        if(k==1) printf("%d
",pow(y,z));
        else if(k==2) 
        {
            if(y%p==0) {printf("Orz, I cannot find x!
");continue;}
            printf("%d
",1ll*pow(y,p-2)*z%p);
        }
        else if(k==3)
        {
           bool flag=false;
           if(y%p==0) {printf("Orz, I cannot find x!
");continue;}
           y%=p,z%=p;
           if(z==1) {printf("0
");continue;}
           int m=sqrt(p)+1;
           M.clear();
           for(int i=0,t=z;i<m;t=1ll*t*y%p,i++) M[t]=i;
           for(int i=1,tt=pow(y,m),t=tt;i<=m;i++,t=1ll*tt*t%p)
                if(M.count(t))
                    {printf("%d
",m*i-M[t]);flag=true;break;}
            if(flag==false)
                printf("Orz, I cannot find x!
");
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/fengxunling/p/10339325.html